1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3mod challenge;
6
7pub mod basic;
8pub mod digest;
9
10use std::fmt::{self, Display, Formatter};
11
12use str_reader::StringReader;
13
14pub use ttpkit_utils::error::Error;
15
16pub use crate::challenge::{AuthChallenge, ChallengeParam};
17
18struct DisplayEscaped<'a> {
20 inner: &'a str,
21}
22
23impl<'a> DisplayEscaped<'a> {
24 const fn new(inner: &'a str) -> Self {
26 Self { inner }
27 }
28}
29
30impl Display for DisplayEscaped<'_> {
31 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
32 for c in self.inner.chars() {
33 match c {
34 '"' => f.write_str("\\\"")?,
35 '\\' => f.write_str("\\\\")?,
36 _ => Display::fmt(&c, f)?,
37 }
38 }
39
40 Ok(())
41 }
42}
43
44trait StringReaderExt {
46 fn parse_quoted_string(&mut self) -> Result<String, Error>;
48}
49
50impl StringReaderExt for StringReader<'_> {
51 fn parse_quoted_string(&mut self) -> Result<String, Error> {
52 let mut reader = StringReader::new(self.as_str());
53
54 reader.match_char('"').map_err(|_| {
55 Error::from_static_msg("quoted string does not start with the double quote sign")
56 })?;
57
58 let mut res = String::new();
59
60 while let Some(c) = reader.current_char() {
61 if c == '\\' {
62 reader.skip_char();
63
64 let c = reader.current_char().ok_or_else(|| {
65 Error::from_static_msg("end of string within an escape sequence")
66 })?;
67
68 res.push(c);
69 } else if c == '"' {
70 break;
71 } else {
72 res.push(c);
73 }
74
75 reader.skip_char();
76 }
77
78 reader.match_char('"').map_err(|_| {
79 Error::from_static_msg("quoted string does not end with the double quote sign")
80 })?;
81
82 *self = reader;
83
84 Ok(res)
85 }
86}