Skip to main content

soup/
message_headers.rs

1use glib::translate::*;
2use glib::{GString, IntoGStr, IntoOptionalGStr};
3use std::collections::HashMap;
4use std::{fmt, ptr};
5
6use crate::MessageHeaders;
7
8impl MessageHeaders {
9    #[doc(alias = "soup_message_headers_get_content_disposition")]
10    pub fn content_disposition(&self) -> Option<(GString, HashMap<String, String>)> {
11        let mut disposition = ptr::null_mut();
12        let mut params = ptr::null_mut();
13        unsafe {
14            if bool::from_glib(ffi::soup_message_headers_get_content_disposition(
15                mut_override(self.to_glib_none().0),
16                &mut disposition,
17                &mut params,
18            )) {
19                let params = if !params.is_null() {
20                    HashMap::from_glib_full(params)
21                } else {
22                    HashMap::new()
23                };
24                Some((GString::from_glib_full(disposition), params))
25            } else {
26                None
27            }
28        }
29    }
30
31    #[doc(alias = "soup_message_headers_set_content_disposition")]
32    pub fn set_content_disposition(
33        &self,
34        disposition: Option<impl IntoGStr>,
35        params: Option<HashMap<String, String>>,
36    ) {
37        disposition.run_with_gstr(|disposition| unsafe {
38            ffi::soup_message_headers_set_content_disposition(
39                self.to_glib_none().0,
40                disposition.to_glib_none().0,
41                params.to_glib_none().0,
42            )
43        })
44    }
45
46    #[doc(alias = "soup_message_headers_get_content_type")]
47    pub fn content_type(&self) -> Option<(GString, HashMap<String, String>)> {
48        let mut params = ptr::null_mut();
49        unsafe {
50            let content_type = ffi::soup_message_headers_get_content_type(
51                mut_override(self.to_glib_none().0),
52                &mut params,
53            );
54            if !content_type.is_null() {
55                let params = if !params.is_null() {
56                    HashMap::from_glib_full(params)
57                } else {
58                    HashMap::new()
59                };
60                Some((GString::from_glib_none(content_type), params))
61            } else {
62                None
63            }
64        }
65    }
66
67    #[doc(alias = "soup_message_headers_set_content_type")]
68    pub fn set_content_type(
69        &self,
70        content_type: Option<impl IntoGStr>,
71        params: Option<HashMap<String, String>>,
72    ) {
73        content_type.run_with_gstr(|content_type| unsafe {
74            ffi::soup_message_headers_set_content_type(
75                self.to_glib_none().0,
76                content_type.to_glib_none().0,
77                params.to_glib_none().0,
78            )
79        })
80    }
81}
82
83impl fmt::Debug for MessageHeaders {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        struct Map<'a>(&'a MessageHeaders);
86        impl fmt::Debug for Map<'_> {
87            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88                let mut map = f.debug_map();
89                self.0.foreach(|name, value| _ = map.entry(&name, &value));
90                map.finish()
91            }
92        }
93        f.debug_tuple("MessageHeaders").field(&Map(self)).finish()
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100    use crate::MessageHeadersType;
101    use std::collections::HashMap;
102
103    #[test]
104    fn content_type_can_be_set_and_read() {
105        let headers = MessageHeaders::new(MessageHeadersType::Request);
106        headers.set_content_type(Some(EXPECTED_CONTENT_TYPE), Some(expected_params()));
107
108        let (content_type, params) = headers
109            .content_type()
110            .expect("content type header to be present");
111
112        assert_eq!(EXPECTED_CONTENT_TYPE, content_type);
113        assert_eq!(expected_params(), params);
114    }
115
116    #[test]
117    fn content_disposition_can_be_set_and_read() {
118        let headers = MessageHeaders::new(MessageHeadersType::Request);
119        headers
120            .set_content_disposition(Some(EXPECTED_CONTENT_DISPOSITION), Some(expected_params()));
121
122        let (content_type, params) = headers
123            .content_disposition()
124            .expect("content disposition header to be present");
125
126        assert_eq!(EXPECTED_CONTENT_DISPOSITION, content_type);
127        assert_eq!(expected_params(), params);
128    }
129
130    const EXPECTED_CONTENT_TYPE: &str = "text/html";
131    const EXPECTED_CONTENT_DISPOSITION: &str = "attachment";
132
133    fn expected_params() -> HashMap<String, String> {
134        [("param".to_owned(), "value".to_owned())]
135            .into_iter()
136            .collect()
137    }
138}