From 51dac3c86207b8fa7abe60ed4f935690f72829c5 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Mon, 30 Dec 2019 12:36:16 +0000 Subject: [PATCH 1/3] Add Debug impls. This commit makes the following changes - Add an opaque `Debug` impl for `Client`. - Add a rich `Debug` impl for `Row`. - Make the `Debug` impl for `Type` clearer. - Change the `Debug` for `Column` to be slightly neater. --- postgres-types/src/lib.rs | 8 +++- tokio-postgres/src/client.rs | 7 ++++ tokio-postgres/src/row.rs | 65 ++++++++++++++++++++++++++++++++- tokio-postgres/src/statement.rs | 15 +++++++- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 0b1a0f2c..f9876e68 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -207,9 +207,15 @@ mod special; mod type_gen; /// A Postgres type. -#[derive(PartialEq, Eq, Clone, Debug, Hash)] +#[derive(PartialEq, Eq, Clone, Hash)] pub struct Type(Inner); +impl fmt::Debug for Type { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.0, fmt) + } +} + impl fmt::Display for Type { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self.schema() { diff --git a/tokio-postgres/src/client.rs b/tokio-postgres/src/client.rs index 0687a08e..2d9b7972 100644 --- a/tokio-postgres/src/client.rs +++ b/tokio-postgres/src/client.rs @@ -21,6 +21,7 @@ use futures::{future, pin_mut, ready, StreamExt, TryStreamExt}; use parking_lot::Mutex; use postgres_protocol::message::backend::Message; use std::collections::HashMap; +use std::fmt; use std::sync::Arc; use std::task::{Context, Poll}; use std::time::Duration; @@ -529,3 +530,9 @@ impl Client { self.inner.sender.is_closed() } } + +impl fmt::Debug for Client { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Client").finish() + } +} diff --git a/tokio-postgres/src/row.rs b/tokio-postgres/src/row.rs index 03c7635b..da313faa 100644 --- a/tokio-postgres/src/row.rs +++ b/tokio-postgres/src/row.rs @@ -100,6 +100,62 @@ pub struct Row { ranges: Vec>>, } +/// A macro to map pg types to rust types, for debug display. +macro_rules! debug_row_type { + ($this:expr; $map:expr; $idx:expr; $name:expr; $type:expr; $($pg_ty:tt => $ty:ty),*) => { + match $type { + $( + &Type::$pg_ty => match <$ty as FromSql>::from_sql_nullable( + &Type::$pg_ty, + $this.0.col_buffer($idx), + ) { + Ok(val) => $map.entry(&$name, &val), + Err(_) => $map.entry(&$name, &""), + }, + )* + _ => $map.entry(&$name, &""), + } + } +} + +impl fmt::Debug for Row { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Provides debug impl for row contents. + struct RowData<'a>(&'a Row); + + impl fmt::Debug for RowData<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut map = f.debug_map(); + for (idx, col) in self.0.columns().iter().enumerate() { + debug_row_type!(self; map; idx; col.name(); col.type_(); + BOOL => bool, + INT2 => i16, + INT4 => i32, + INT8 => i64, + FLOAT4 => f32, + FLOAT8 => f64, + VARCHAR => String, + BPCHAR => String, + TEXT => String, + JSON => String, + XML => String, + TIMESTAMPTZ => std::time::SystemTime, + TIMESTAMP => std::time::SystemTime, + BYTEA => Vec + // More types could be added here. + ); + } + map.finish() + } + } + + f.debug_struct("Row") + .field("columns", &self.columns()) + .field("data", &RowData(self)) + .finish() + } +} + impl Row { pub(crate) fn new(statement: Statement, body: DataRowBody) -> Result { let ranges = body.ranges().collect().map_err(Error::parse)?; @@ -170,8 +226,13 @@ impl Row { )); } - let buf = self.ranges[idx].clone().map(|r| &self.body.buffer()[r]); - FromSql::from_sql_nullable(ty, buf).map_err(|e| Error::from_sql(e, idx)) + FromSql::from_sql_nullable(ty, self.col_buffer(idx)).map_err(|e| Error::from_sql(e, idx)) + } + + /// Get the raw bytes for the column at the given index. + fn col_buffer(&self, idx: usize) -> Option<&[u8]> { + let range = self.ranges[idx].to_owned()?; + Some(&self.body.buffer()[range]) } } diff --git a/tokio-postgres/src/statement.rs b/tokio-postgres/src/statement.rs index d8fa1911..97561a8e 100644 --- a/tokio-postgres/src/statement.rs +++ b/tokio-postgres/src/statement.rs @@ -3,7 +3,10 @@ use crate::codec::FrontendMessage; use crate::connection::RequestMessages; use crate::types::Type; use postgres_protocol::message::frontend; -use std::sync::{Arc, Weak}; +use std::{ + fmt, + sync::{Arc, Weak}, +}; struct StatementInner { client: Weak, @@ -62,7 +65,6 @@ impl Statement { } /// Information about a column of a query. -#[derive(Debug)] pub struct Column { name: String, type_: Type, @@ -83,3 +85,12 @@ impl Column { &self.type_ } } + +impl fmt::Debug for Column { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Column") + .field("name", &self.name) + .field("type", &self.type_) + .finish() + } +} From 369427b38179d15d0ec11f4ee315a16d4aab96e5 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Mon, 30 Dec 2019 13:09:11 +0000 Subject: [PATCH 2/3] Allow clippy lint in macro output. --- tokio-postgres/src/row.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tokio-postgres/src/row.rs b/tokio-postgres/src/row.rs index da313faa..05a5117e 100644 --- a/tokio-postgres/src/row.rs +++ b/tokio-postgres/src/row.rs @@ -124,6 +124,7 @@ impl fmt::Debug for Row { struct RowData<'a>(&'a Row); impl fmt::Debug for RowData<'_> { + #[allow(clippy::match_ref_pats)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut map = f.debug_map(); for (idx, col) in self.0.columns().iter().enumerate() { From 6fd69dfd474d378ecdeecc77b1e9ec1acbb9a749 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Tue, 21 Jan 2020 17:21:05 +0000 Subject: [PATCH 3/3] Make requested changes --- tokio-postgres/src/row.rs | 49 --------------------------------------- 1 file changed, 49 deletions(-) diff --git a/tokio-postgres/src/row.rs b/tokio-postgres/src/row.rs index 05a5117e..842216ad 100644 --- a/tokio-postgres/src/row.rs +++ b/tokio-postgres/src/row.rs @@ -100,59 +100,10 @@ pub struct Row { ranges: Vec>>, } -/// A macro to map pg types to rust types, for debug display. -macro_rules! debug_row_type { - ($this:expr; $map:expr; $idx:expr; $name:expr; $type:expr; $($pg_ty:tt => $ty:ty),*) => { - match $type { - $( - &Type::$pg_ty => match <$ty as FromSql>::from_sql_nullable( - &Type::$pg_ty, - $this.0.col_buffer($idx), - ) { - Ok(val) => $map.entry(&$name, &val), - Err(_) => $map.entry(&$name, &""), - }, - )* - _ => $map.entry(&$name, &""), - } - } -} - impl fmt::Debug for Row { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Provides debug impl for row contents. - struct RowData<'a>(&'a Row); - - impl fmt::Debug for RowData<'_> { - #[allow(clippy::match_ref_pats)] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut map = f.debug_map(); - for (idx, col) in self.0.columns().iter().enumerate() { - debug_row_type!(self; map; idx; col.name(); col.type_(); - BOOL => bool, - INT2 => i16, - INT4 => i32, - INT8 => i64, - FLOAT4 => f32, - FLOAT8 => f64, - VARCHAR => String, - BPCHAR => String, - TEXT => String, - JSON => String, - XML => String, - TIMESTAMPTZ => std::time::SystemTime, - TIMESTAMP => std::time::SystemTime, - BYTEA => Vec - // More types could be added here. - ); - } - map.finish() - } - } - f.debug_struct("Row") .field("columns", &self.columns()) - .field("data", &RowData(self)) .finish() } }