From 51dac3c86207b8fa7abe60ed4f935690f72829c5 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Mon, 30 Dec 2019 12:36:16 +0000 Subject: [PATCH] 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() + } +}