cookie_monster/cookie/
serialize.rs1use crate::{
2 Error, SameSite,
3 cookie::parse::{find_invalid_cookie_value, is_token, trim_quotes},
4};
5
6use super::Cookie;
7use std::fmt::Write;
8
9impl Cookie {
10 pub fn serialize(&self) -> crate::Result<String> {
11 self.serialize_inner(|name, value, buf| {
12 let trimmed_value = trim_quotes(value);
15
16 if let Some(invalid_char) = find_invalid_cookie_value(trimmed_value) {
17 return Err(Error::InvalidValue(invalid_char));
18 } else if !is_token(name) {
19 return Err(Error::InvalidName);
20 }
21
22 let _ = write!(buf, "{name}={value}");
23 Ok(())
24 })
25 }
26
27 #[cfg(feature = "percent-encode")]
28 pub fn serialize_encoded(&self) -> crate::Result<String> {
29 use crate::cookie::encoding::{encode_name, encode_value};
30
31 self.serialize_inner(|name, value, buf| {
32 let _ = write!(buf, "{}={}", encode_name(name), encode_value(value));
34 Ok(())
35 })
36 }
37
38 fn serialize_inner(
39 &self,
40 callback: impl Fn(&str, &str, &mut String) -> crate::Result<()>,
41 ) -> crate::Result<String> {
42 let value = self.value();
43 let name = self.name();
44 let domain = self.domain();
45 let path = self.path();
46
47 if name.is_empty() {
48 return Err(Error::NameEmpty);
49 }
50
51 let buf_len = name.len()
52 + value.len()
53 + domain.map(str::len).unwrap_or_default()
54 + path.map(str::len).unwrap_or_default();
55
56 let mut buf = String::with_capacity(buf_len + 110);
59
60 callback(name, value, &mut buf)?;
63
64 if let Some(max_age) = self.max_age_secs() {
66 buf.push_str("; Max-Age=");
67 write!(&mut buf, "{max_age}").expect("Failed to write Max-Age seconds");
68 }
69
70 self.serialize_domain(&mut buf);
71
72 self.serialize_path(&mut buf)?;
73
74 if self.secure() || self.partitioned() || self.same_site() == Some(SameSite::None) {
76 buf.push_str("; Secure");
77 }
78
79 if self.http_only() {
80 buf.push_str("; HttpOnly");
81 }
82
83 if self.partitioned() {
84 buf.push_str("; Partitioned");
85 }
86
87 self.serialize_same_site(&mut buf);
88
89 self.serialize_expire(&mut buf)?;
90 Ok(buf)
91 }
92}