mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-30 18:34:36 +01:00
port Extensions from http crate #315
This commit is contained in:
parent
33050f55a3
commit
879b2b5bde
@ -57,6 +57,7 @@ base64 = "0.9"
|
||||
bitflags = "1.0"
|
||||
failure = "0.1.1"
|
||||
h2 = "0.1"
|
||||
fnv = "1.0.5"
|
||||
http = "^0.1.5"
|
||||
httparse = "1.2"
|
||||
http-range = "0.1"
|
||||
|
90
src/extensions.rs
Normal file
90
src/extensions.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use std::any::{Any, TypeId};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::hash::BuildHasherDefault;
|
||||
|
||||
use fnv::FnvHasher;
|
||||
|
||||
type AnyMap = HashMap<TypeId, Box<Any>, BuildHasherDefault<FnvHasher>>;
|
||||
|
||||
/// A type map of request extensions.
|
||||
pub struct Extensions {
|
||||
map: AnyMap,
|
||||
}
|
||||
|
||||
impl Extensions {
|
||||
/// Create an empty `Extensions`.
|
||||
#[inline]
|
||||
pub(crate) fn new() -> Extensions {
|
||||
Extensions {
|
||||
map: HashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a type into this `Extensions`.
|
||||
///
|
||||
/// If a extension of this type already existed, it will
|
||||
/// be returned.
|
||||
pub fn insert<T: 'static>(&mut self, val: T) {
|
||||
self.map.insert(TypeId::of::<T>(), Box::new(val));
|
||||
}
|
||||
|
||||
/// Get a reference to a type previously inserted on this `Extensions`.
|
||||
pub fn get<T: 'static>(&self) -> Option<&T> {
|
||||
self.map
|
||||
.get(&TypeId::of::<T>())
|
||||
.and_then(|boxed| (&**boxed as &(Any + 'static)).downcast_ref())
|
||||
}
|
||||
|
||||
/// Get a mutable reference to a type previously inserted on this `Extensions`.
|
||||
pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
|
||||
self.map
|
||||
.get_mut(&TypeId::of::<T>())
|
||||
.and_then(|boxed| (&mut **boxed as &mut (Any + 'static)).downcast_mut())
|
||||
}
|
||||
|
||||
/// Remove a type from this `Extensions`.
|
||||
///
|
||||
/// If a extension of this type existed, it will be returned.
|
||||
pub fn remove<T: 'static>(&mut self) -> Option<T> {
|
||||
self.map.remove(&TypeId::of::<T>()).and_then(|boxed| {
|
||||
//TODO: we can use unsafe and remove double checking the type id
|
||||
(boxed as Box<Any + 'static>)
|
||||
.downcast()
|
||||
.ok()
|
||||
.map(|boxed| *boxed)
|
||||
})
|
||||
}
|
||||
|
||||
/// Clear the `Extensions` of all inserted extensions.
|
||||
#[inline]
|
||||
pub fn clear(&mut self) {
|
||||
self.map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Extensions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Extensions").finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extensions() {
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct MyType(i32);
|
||||
|
||||
let mut extensions = Extensions::new();
|
||||
|
||||
extensions.insert(5i32);
|
||||
extensions.insert(MyType(10));
|
||||
|
||||
assert_eq!(extensions.get(), Some(&5i32));
|
||||
assert_eq!(extensions.get_mut(), Some(&mut 5i32));
|
||||
|
||||
assert_eq!(extensions.remove::<i32>(), Some(5i32));
|
||||
assert!(extensions.get::<i32>().is_none());
|
||||
|
||||
assert_eq!(extensions.get::<bool>(), None);
|
||||
assert_eq!(extensions.get(), Some(&MyType(10)));
|
||||
}
|
@ -9,12 +9,13 @@ use cookie::Cookie;
|
||||
use failure;
|
||||
use futures::{Async, Poll, Stream};
|
||||
use futures_cpupool::CpuPool;
|
||||
use http::{header, Extensions, HeaderMap, Method, StatusCode, Uri, Version};
|
||||
use http::{header, HeaderMap, Method, StatusCode, Uri, Version};
|
||||
use tokio_io::AsyncRead;
|
||||
use url::{form_urlencoded, Url};
|
||||
|
||||
use body::Body;
|
||||
use error::{CookieParseError, PayloadError, UrlGenerationError};
|
||||
use extensions::Extensions;
|
||||
use handler::FromRequest;
|
||||
use httpmessage::HttpMessage;
|
||||
use httpresponse::{HttpResponse, HttpResponseBuilder};
|
||||
|
@ -97,6 +97,7 @@ extern crate time;
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
extern crate fnv;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
@ -155,6 +156,7 @@ mod application;
|
||||
mod body;
|
||||
mod context;
|
||||
mod de;
|
||||
mod extensions;
|
||||
mod extractor;
|
||||
mod handler;
|
||||
mod header;
|
||||
@ -188,6 +190,7 @@ pub use application::App;
|
||||
pub use body::{Binary, Body};
|
||||
pub use context::HttpContext;
|
||||
pub use error::{Error, ResponseError, Result};
|
||||
pub use extensions::Extensions;
|
||||
pub use extractor::{Form, Path, Query};
|
||||
pub use handler::{
|
||||
AsyncResponder, Either, FromRequest, FutureResponse, Responder, State,
|
||||
|
Loading…
Reference in New Issue
Block a user