sdp_rs/tokenizers/
key_optvalue.rs1use crate::TResult;
2
3#[derive(Debug, PartialEq, Eq, Clone)]
4pub struct Tokenizer<'a, const C: char> {
5 pub key: &'a str,
6 pub value: Option<&'a str>,
7}
8
9impl<'a, const C: char> Tokenizer<'a, C> {
10 pub fn tokenize(part: &'a str) -> TResult<'a, Self> {
11 use crate::parser_utils::*;
12 use nom::{branch::alt, bytes::complete::tag, combinator::rest, sequence::preceded};
13
14 let (rem, key_with_value) = preceded(tag(Self::prefix().as_str()), until_newline)(part)?;
15 let (value, key) = alt((until_stopbreak_of(":"), rest))(key_with_value)?;
16 let value = match value.is_empty() {
17 true => None,
18 false => Some(value),
19 };
20
21 Ok((rem, (key, value).into()))
22 }
23
24 fn prefix() -> String {
27 format!("{}=", C)
28 }
29}
30
31impl<'a, const C: char> From<(&'a str, Option<&'a str>)> for Tokenizer<'a, C> {
32 fn from((key, value): (&'a str, Option<&'a str>)) -> Self {
33 Self { key, value }
34 }
35}
36
37impl<'a, const C: char> From<(&'a str, &'a str)> for Tokenizer<'a, C> {
38 fn from((key, value): (&'a str, &'a str)) -> Self {
39 Self {
40 key,
41 value: Some(value),
42 }
43 }
44}
45
46impl<'a, const C: char> From<&'a str> for Tokenizer<'a, C> {
47 fn from(key: &'a str) -> Self {
48 Self { key, value: None }
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn tokenizer1() {
58 let key_optvalue = concat!("a=recvonly\r\nsomething");
59
60 assert_eq!(
61 Tokenizer::<'a'>::tokenize(key_optvalue),
62 Ok((
63 "something",
64 Tokenizer {
65 key: "recvonly",
66 value: None,
67 }
68 )),
69 );
70 }
71
72 #[test]
73 fn tokenizer2() {
74 let key_optvalue = concat!("a=rtpmap:99 h263-1998/90000\r\nsomething");
75
76 assert_eq!(
77 Tokenizer::<'a'>::tokenize(key_optvalue),
78 Ok((
79 "something",
80 Tokenizer {
81 key: "rtpmap",
82 value: Some("99 h263-1998/90000"),
83 }
84 )),
85 );
86 }
87}