multipart/
lib.rs

1// Copyright 2016 `multipart` Crate Developers
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7//! Client- and server-side abstractions for HTTP `multipart/form-data` requests.
8//!
9//! ### Features:
10//! This documentation is built with all features enabled.
11//!
12//! * `client`: The client-side abstractions for generating multipart requests.
13//!
14//! * `server`: The server-side abstractions for parsing multipart requests.
15//!
16//! * `mock`: Provides mock implementations of core `client` and `server` traits for debugging
17//! or non-standard use.
18//!
19//! * `hyper`: Integration with the [Hyper](https://crates.io/crates/hyper) HTTP library
20//! for client and/or server depending on which other feature flags are set.
21//!
22//! * `iron`: Integration with the [Iron](http://crates.io/crates/iron) web application
23//! framework. See the [`server::iron`](server/iron/index.html) module for more information.
24//!
25//! * `nickel` (returning in 0.14!): Integration with the [Nickel](https://crates.io/crates/nickel)
26//! web application framework. See the [`server::nickel`](server/nickel/index.html) module for more
27//! information.
28//!
29//! * `tiny_http`: Integration with the [`tiny_http`](https://crates.io/crates/tiny_http)
30//! crate. See the [`server::tiny_http`](server/tiny_http/index.html) module for more information.
31//!
32//! ### Note: Work in Progress
33//! I have left a number of Request-for-Comments (RFC) questions on various APIs and other places
34//! in the code as there are some cases where I'm not sure what the desirable behavior is.
35//!
36//! I have opened an issue as a place to collect responses and discussions for these questions
37//! [on Github](https://github.com/abonander/multipart/issues/96). Please quote the RFC-statement
38//! (and/or link to its source line) and provide your feedback there.
39#![cfg_attr(feature = "clippy", feature(plugin))]
40#![cfg_attr(feature = "clippy", plugin(clippy))]
41#![cfg_attr(feature = "clippy", deny(clippy))]
42#![cfg_attr(feature = "bench", feature(test))]
43#![deny(missing_docs)]
44
45#[macro_use]
46extern crate log;
47
48extern crate mime;
49extern crate mime_guess;
50extern crate rand;
51extern crate tempfile;
52
53#[cfg(feature = "quick-error")]
54#[macro_use]
55extern crate quick_error;
56
57#[cfg(feature = "server")]
58extern crate safemem;
59
60#[cfg(feature = "hyper")]
61extern crate hyper;
62
63#[cfg(feature = "iron")]
64extern crate iron;
65
66#[cfg(feature = "tiny_http")]
67extern crate tiny_http;
68
69#[cfg(test)]
70extern crate env_logger;
71
72#[cfg(any(feature = "mock", test))]
73pub mod mock;
74
75use rand::Rng;
76
77/// Chain a series of results together, with or without previous results.
78///
79/// ```
80/// #[macro_use] extern crate multipart;
81///
82/// fn try_add_one(val: u32) -> Result<u32, u32> {
83///     if val < 5 {
84///         Ok(val + 1)
85///     } else {
86///         Err(val)
87///     }
88/// }
89///
90/// fn main() {
91///     let res = chain_result! {
92///         try_add_one(1),
93///         prev -> try_add_one(prev),
94///         prev -> try_add_one(prev),
95///         prev -> try_add_one(prev)
96///     };
97///
98///     println!("{:?}", res);
99/// }
100///
101/// ```
102#[macro_export]
103macro_rules! chain_result {
104    ($first_expr:expr, $($try_expr:expr),*) => (
105        $first_expr $(.and_then(|_| $try_expr))*
106    );
107    ($first_expr:expr, $($($arg:ident),+ -> $try_expr:expr),*) => (
108        $first_expr $(.and_then(|$($arg),+| $try_expr))*
109    );
110}
111
112#[cfg(feature = "client")]
113pub mod client;
114#[cfg(feature = "server")]
115pub mod server;
116
117#[cfg(all(test, feature = "client", feature = "server"))]
118mod local_test;
119
120fn random_alphanumeric(len: usize) -> String {
121    rand::thread_rng()
122        .sample_iter(&rand::distributions::Alphanumeric)
123        .take(len)
124        .map(|c| c as char)
125        .collect()
126}
127
128#[cfg(test)]
129fn init_log() {
130    let _ = env_logger::try_init();
131}