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}