bifrost_sdp/
encryption_key.rs1use std::fmt;
2
3use http::Uri;
4use nom::{
5 branch::alt,
6 bytes::complete::{is_not, tag},
7 character::complete::line_ending,
8 combinator::map_res,
9 IResult,
10};
11
12use crate::Parse;
13
14#[derive(Clone, Debug, PartialEq)]
17pub enum EncryptionKey {
18 Clear(String),
19 Base64(String),
20 Uri(Uri),
21 Prompt,
22}
23
24impl fmt::Display for EncryptionKey {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 match self {
27 Self::Clear(key) => writeln!(f, "k=clear:{}\r", key),
28 Self::Base64(key) => writeln!(f, "k=base64:{}\r", key),
29 Self::Uri(uri) => writeln!(f, "k=uri:{}\r", uri),
30 Self::Prompt => writeln!(f, "k=prompt\r"),
31 }
32 }
33}
34
35impl Parse for EncryptionKey {
36 fn parse(input: &str) -> IResult<&str, Self> {
37 let (rest, _) = tag("k=")(input)?;
40 let (rest, key) = alt((parse_clear, parse_base64, parse_uri, parse_prompt))(rest)?;
41 let (rest, _) = line_ending(rest)?;
42 Ok((rest, key))
43 }
44}
45
46fn parse_clear(input: &str) -> IResult<&str, EncryptionKey> {
47 let (rest, _) = tag("clear:")(input)?;
48 let (rest, key) = is_not("\r\n")(rest)?;
49 Ok((rest, EncryptionKey::Clear(key.to_owned())))
50}
51
52fn parse_base64(input: &str) -> IResult<&str, EncryptionKey> {
53 let (rest, _) = tag("base64:")(input)?;
54 let (rest, key) = is_not("\r\n")(rest)?;
55 Ok((rest, EncryptionKey::Base64(key.to_owned())))
56}
57
58fn parse_uri(input: &str) -> IResult<&str, EncryptionKey> {
59 let (rest, _) = tag("uri:")(input)?;
60 let (rest, key) = map_res(is_not("\r\n"), str::parse)(rest)?;
61 Ok((rest, EncryptionKey::Uri(key)))
62}
63
64fn parse_prompt(input: &str) -> IResult<&str, EncryptionKey> {
65 let (rest, _) = tag("prompt")(input)?;
66 Ok((rest, EncryptionKey::Prompt))
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use crate::test_util::{assert_err, assert_parse_display};
73
74 #[test]
75 fn test_clear() {
76 assert_parse_display(
77 "k=clear:foo\r\nmore",
78 "more",
79 &EncryptionKey::Clear("foo".to_owned()),
80 "k=clear:foo\r\n",
81 );
82 assert_err::<EncryptionKey>("k=clear\r\nmore");
83 assert_err::<EncryptionKey>("k=clear:\r\nmore");
84 }
85
86 #[test]
87 fn test_base64() {
88 assert_parse_display(
89 "k=base64:foo\r\n\rmore",
90 "\rmore",
91 &EncryptionKey::Base64("foo".to_owned()),
92 "k=base64:foo\r\n",
93 );
94 assert_err::<EncryptionKey>("k=base64\r\nmore");
95 assert_err::<EncryptionKey>("k=base64:\r\nmore");
96 }
97
98 #[test]
99 fn test_uri() {
100 let uri_str = "https://example.org/key";
101 let uri = uri_str.parse().unwrap();
102
103 assert_parse_display(
104 &format!("k=uri:{}\r\n\nmore\r", uri_str),
105 "\nmore\r",
106 &EncryptionKey::Uri(uri),
107 &format!("k=uri:{}\r\n", uri_str),
108 );
109 assert_err::<EncryptionKey>("k=uri\r\nmore");
110 assert_err::<EncryptionKey>("k=uri:\r\nmore");
111 assert_err::<EncryptionKey>("k=uri:!@#$\r\nmore");
112 }
113
114 #[test]
115 fn test_prompt() {
116 assert_parse_display(
117 "k=prompt\r\nmore",
118 "more",
119 &EncryptionKey::Prompt,
120 "k=prompt\r\n",
121 );
122 assert_err::<EncryptionKey>("k=prompt:foo\r\nmore");
123 assert_err::<EncryptionKey>("k=prompt:\r\nmore");
124 }
125
126 #[test]
127 fn test_invalid() {
128 assert_err::<EncryptionKey>("k=foo\r\nmore");
129 assert_err::<EncryptionKey>("k=foo:\r\nmore");
130 assert_err::<EncryptionKey>("k=foo:bar\r\nmore");
131 }
132}