mp4_atom/moov/trak/mdia/minf/dinf/dref/
url.rs1use crate::*;
2
3ext! {
4 name: Url,
5 versions: [0],
6 flags: {
7 self_contained = 0,
8 }
9}
10
11#[derive(Debug, Clone, PartialEq, Eq, Default)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Url {
14 pub location: String,
15}
16
17impl AtomExt for Url {
18 type Ext = UrlExt;
19
20 const KIND_EXT: FourCC = FourCC::new(b"url ");
21
22 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: UrlExt) -> Result<Self> {
23 let location = match buf.has_remaining() {
24 true => String::decode(buf)?,
25 false => "".to_string(),
26 };
27
28 Ok(Url { location })
29 }
30
31 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<UrlExt> {
32 if !self.location.is_empty() {
33 self.location.as_str().encode(buf)?;
34 }
35
36 Ok(UrlExt {
37 self_contained: self.location.is_empty(),
39 ..Default::default()
40 })
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 const ENCODED_EMPTY: &[u8] = &[
49 0x00, 0x00, 0x00, 0x0c, b'u', b'r', b'l', b' ', 0x00, 0x00, 0x00, 0x01,
50 ];
51 #[test]
52 fn test_url_empty_encode() {
53 let url = Url {
54 location: "".into(),
55 };
56
57 let mut buf = Vec::new();
58 url.encode(&mut buf).unwrap();
59
60 assert_eq!(buf.as_slice(), ENCODED_EMPTY);
61 }
62
63 #[test]
64 fn test_url_empty_decode() {
65 let buf = &mut std::io::Cursor::new(&ENCODED_EMPTY);
66
67 let url = Url::decode(buf).expect("failed to decode url");
68
69 assert_eq!(
70 url,
71 Url {
72 location: "".into(),
73 }
74 );
75 }
76
77 const ENCODED_HTTP: &[u8] = &[
78 0x00, 0x00, 0x00, 0x2a, b'u', b'r', b'l', b' ', 0x00, 0x00, 0x00, 0x00, b'h', b't', b't',
79 b'p', b's', b':', b'/', b'/', b'e', b'x', b'a', b'm', b'p', b'l', b'e', b'.', b'c', b'o',
80 b'm', b'/', b'd', b'a', b't', b'a', b'.', b'b', b'l', b'o', b'b', 0,
81 ];
82 #[test]
83 fn test_url_http_encode() {
84 let url = Url {
85 location: "https://example.com/data.blob".into(),
86 };
87
88 let mut buf = Vec::new();
89 url.encode(&mut buf).unwrap();
90
91 assert_eq!(buf.as_slice(), ENCODED_HTTP);
92 }
93
94 #[test]
95 fn test_url_http_decode() {
96 let buf = &mut std::io::Cursor::new(&ENCODED_HTTP);
97
98 let url = Url::decode(buf).expect("failed to decode url");
99 assert_eq!(
100 url,
101 Url {
102 location: "https://example.com/data.blob".into(),
103 }
104 );
105 }
106}