cookie_store/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2//! # cookie_store
3//! Provides an implementation for storing and retrieving [`Cookie`]s per the path and domain matching
4//! rules specified in [RFC6265](https://datatracker.ietf.org/doc/html/rfc6265).
5//!
6//! ## Example
7//! Please refer to the [reqwest_cookie_store](https://crates.io/crates/reqwest_cookie_store) for
8//! an example of using this library along with [reqwest](https://crates.io/crates/reqwest).
9//!
10//! ## Feature flags
11#![doc = document_features::document_features!()]
12
13use idna;
14
15pub use ::cookie::{Cookie as RawCookie, ParseError as RawCookieParseError};
16
17mod cookie;
18pub use crate::cookie::Error as CookieError;
19pub use crate::cookie::{Cookie, CookieResult};
20mod cookie_domain;
21pub use crate::cookie_domain::CookieDomain;
22mod cookie_expiration;
23pub use crate::cookie_expiration::CookieExpiration;
24mod cookie_path;
25pub use crate::cookie_path::CookiePath;
26mod cookie_store;
27pub use crate::cookie_store::{CookieStore, StoreAction};
28#[cfg(feature = "serde")]
29pub mod serde;
30mod utils;
31
32#[derive(Debug)]
33pub struct IdnaErrors(idna::Errors);
34
35impl std::fmt::Display for IdnaErrors {
36    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
37        write!(f, "IDNA errors: {:#?}", self.0)
38    }
39}
40
41impl std::error::Error for IdnaErrors {}
42
43impl From<idna::Errors> for IdnaErrors {
44    fn from(e: idna::Errors) -> Self {
45        IdnaErrors(e)
46    }
47}
48
49pub type Error = Box<dyn std::error::Error + Send + Sync>;
50pub type Result<T> = std::result::Result<T, Error>;
51
52#[cfg(feature = "serde")]
53pub(crate) mod rfc3339_fmt {
54
55    pub(crate) const RFC3339_FORMAT: &[time::format_description::FormatItem] =
56        time::macros::format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]Z");
57
58    pub(super) fn serialize<S>(t: &time::OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
59    where
60        S: serde::Serializer,
61    {
62        use serde::ser::Error;
63        // An explicit format string is used here, instead of time::format_description::well_known::Rfc3339, to explicitly
64        // utilize the 'Z' terminator instead of +00:00 format for Zulu time.
65        let s = t.format(&RFC3339_FORMAT).map_err(|e| {
66            println!("{}", e);
67            S::Error::custom(format!(
68                "Could not parse datetime '{}' as RFC3339 UTC format: {}",
69                t, e
70            ))
71        })?;
72        serializer.serialize_str(&s)
73    }
74
75    pub(super) fn deserialize<'de, D>(t: D) -> Result<time::OffsetDateTime, D::Error>
76    where
77        D: serde::Deserializer<'de>,
78    {
79        use serde::{de::Error, Deserialize};
80
81        let s = String::deserialize(t)?;
82        time::OffsetDateTime::parse(&s, &time::format_description::well_known::Rfc3339).map_err(
83            |e| {
84                D::Error::custom(format!(
85                    "Could not parse string '{}' as RFC3339 UTC format: {}",
86                    s, e
87                ))
88            },
89        )
90    }
91}