Skip to content

Commit

Permalink
Add Debug impl for Store
Browse files Browse the repository at this point in the history
  • Loading branch information
tirr-c committed Jan 10, 2019
1 parent 73769de commit 262985a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 12 deletions.
2 changes: 1 addition & 1 deletion examples/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use tide::{head::Path, ExtractConfiguration};

/// A type that represents how much value will be added by the `add` handler.
#[derive(Clone, Default)]
#[derive(Clone, Debug, Default)]
struct IncreaseBy(i32);

async fn add(
Expand Down
5 changes: 3 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use futures::{
use hyper::service::Service;
use std::{
any::Any,
fmt::Debug,
ops::{Deref, DerefMut},
sync::Arc,
};
Expand Down Expand Up @@ -147,12 +148,12 @@ impl<Data: Clone + Send + Sync + 'static> App<Data> {
}

/// Add a default configuration `item` for the whole app.
pub fn config<T: Any + Clone + Send + Sync>(&mut self, item: T) -> &mut Self {
pub fn config<T: Any + Debug + Clone + Send + Sync>(&mut self, item: T) -> &mut Self {
self.router.config(item);
self
}

pub fn get_item<T: Any + Clone + Send + Sync>(&self) -> Option<&T> {
pub fn get_item<T: Any + Debug + Clone + Send + Sync>(&self) -> Option<&T> {
self.router.get_item()
}

Expand Down
30 changes: 26 additions & 4 deletions src/configuration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::fmt::{self, Debug};

use futures::future::FutureObj;

Expand All @@ -15,11 +16,12 @@ trait StoreItem: Any + Send + Sync {
fn clone_any(&self) -> Box<dyn StoreItem>;
fn as_dyn_any(&self) -> &(dyn Any + Send + Sync);
fn as_dyn_any_mut(&mut self) -> &mut (dyn Any + Send + Sync);
fn fmt_debug(&self, fmt: &mut fmt::Formatter) -> fmt::Result;
}

impl<T> StoreItem for T
where
T: Any + Clone + Send + Sync,
T: Any + Debug + Clone + Send + Sync,
{
fn clone_any(&self) -> Box<dyn StoreItem> {
Box::new(self.clone())
Expand All @@ -32,6 +34,10 @@ where
fn as_dyn_any_mut(&mut self) -> &mut (dyn Any + Send + Sync) {
self
}

fn fmt_debug(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.fmt(fmt)
}
}

impl Clone for Box<dyn StoreItem> {
Expand All @@ -40,12 +46,24 @@ impl Clone for Box<dyn StoreItem> {
}
}

impl Debug for Box<dyn StoreItem> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
(&**self).fmt_debug(fmt)
}
}

/// A cloneable typemap for saving per-endpoint configuration.
///
/// Store is mostly managed by `App` and `Router`, so this is normally not used directly.
#[derive(Clone)]
pub struct Store(HashMap<TypeId, Box<dyn StoreItem>>);

impl Debug for Store {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_set().entries(self.0.values()).finish()
}
}

impl Store {
pub(crate) fn new() -> Self {
Store(HashMap::new())
Expand All @@ -57,15 +75,15 @@ impl Store {
}

/// Retrieve the configuration item of given type, returning `None` if it is not found.
pub fn read<T: Any + Clone + Send + Sync>(&self) -> Option<&T> {
pub fn read<T: Any + Debug + Clone + Send + Sync>(&self) -> Option<&T> {
let id = TypeId::of::<T>();
self.0
.get(&id)
.and_then(|v| (**v).as_dyn_any().downcast_ref::<T>())
}

/// Save the given configuration item.
pub fn write<T: Any + Clone + Send + Sync>(&mut self, value: T) {
pub fn write<T: Any + Debug + Clone + Send + Sync>(&mut self, value: T) {
let id = TypeId::of::<T>();
self.0.insert(id, Box::new(value) as Box<dyn StoreItem>);
}
Expand All @@ -77,7 +95,11 @@ impl Store {
/// will be `None`.
pub struct ExtractConfiguration<T>(pub Option<T>);

impl<S: 'static, T: Any + Clone + Send + Sync + 'static> Extract<S> for ExtractConfiguration<T> {
impl<S, T> Extract<S> for ExtractConfiguration<T>
where
S: 'static,
T: Any + Debug + Clone + Send + Sync + 'static,
{
type Fut = FutureObj<'static, Result<Self, Response>>;

fn extract(
Expand Down
13 changes: 11 additions & 2 deletions src/middleware/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::any::Any;
use std::fmt::Debug;
use std::sync::Arc;

use futures::future::FutureObj;

use crate::{router::EndpointData, Request, Response, RouteMatch};
use crate::{configuration::Store, router::EndpointData, Request, Response, RouteMatch};

mod default_headers;
pub mod logger;
Expand Down Expand Up @@ -35,10 +36,18 @@ pub struct RequestContext<'a, Data> {

impl<'a, Data: Clone + Send> RequestContext<'a, Data> {
/// Get a configuration item of given type from the endpoint.
pub fn get_item<T: Any + Clone + Send + Sync>(&self) -> Option<&T> {
pub fn get_item<T: Any + Debug + Clone + Send + Sync>(&self) -> Option<&T> {
self.endpoint.store.read::<T>()
}

/// Get the configuration store for this request.
///
/// This is for debug purposes. `Store` implements `Debug`, so the store can be inspected using
/// `{:?}` formatter.
pub fn store(&self) -> &Store {
&self.endpoint.store
}

/// Consume this context, and run remaining middleware chain to completion.
pub fn next(mut self) -> FutureObj<'a, Response> {
if let Some((current, next)) = self.next_middleware.split_first() {
Expand Down
7 changes: 4 additions & 3 deletions src/router.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::any::Any;
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::Arc;

use crate::{
Expand Down Expand Up @@ -158,7 +159,7 @@ impl<Data: Clone + Send + Sync + 'static> Router<Data> {
/// Add a default configuration `item` for this router.
///
/// The default configuration will be applied when the router setup ends.
pub fn config<T: Any + Clone + Send + Sync>(&mut self, item: T) -> &mut Self {
pub fn config<T: Any + Debug + Clone + Send + Sync>(&mut self, item: T) -> &mut Self {
self.store_base.write(item);
self
}
Expand Down Expand Up @@ -186,7 +187,7 @@ impl<Data> Router<Data> {
}
}

pub(crate) fn get_item<T: Any + Clone + Send + Sync>(&self) -> Option<&T> {
pub(crate) fn get_item<T: Any + Debug + Clone + Send + Sync>(&self) -> Option<&T> {
self.store_base.read()
}
}
Expand All @@ -201,7 +202,7 @@ pub struct EndpointData<Data> {

impl<Data> EndpointData<Data> {
/// Add a configuration `item` for this endpoint.
pub fn config<T: Any + Clone + Send + Sync>(&mut self, item: T) -> &mut Self {
pub fn config<T: Any + Debug + Clone + Send + Sync>(&mut self, item: T) -> &mut Self {
self.store.write(item);
self
}
Expand Down

0 comments on commit 262985a

Please sign in to comment.