authorized_keys/openssh/v2/parse/
mod.rs

1mod atoms;
2mod full;
3mod mapped;
4mod parts;
5
6use super::models::{KeyAuthorization, KeysFile, KeysFileLine};
7use std::str::FromStr;
8
9impl FromStr for KeyAuthorization {
10    type Err = String;
11
12    fn from_str(s: &str) -> Result<Self, Self::Err> {
13        full::key_authorization(s)
14            .map(|(_, res)| res)
15            .map_err(|e| match e {
16                nom::Err::Incomplete(_) => unreachable!(),
17                nom::Err::Error(err) | nom::Err::Failure(err) => err.0.to_string(),
18            })
19    }
20}
21
22impl FromStr for KeysFile {
23    type Err = String;
24
25    fn from_str(s: &str) -> Result<Self, Self::Err> {
26        let in_lines = s.lines().enumerate().collect::<Vec<_>>();
27
28        let mut lines: Vec<KeysFileLine> = Vec::with_capacity(in_lines.len());
29
30        for (line_no, line) in in_lines {
31            let comment_indicator = line.chars().skip_while(char::is_ascii_whitespace).next();
32
33            // line was all whitespace, or first non-whitespace was comment char
34            lines.push(
35                if comment_indicator == None || comment_indicator == Some('#') {
36                    KeysFileLine::Comment(line.to_owned())
37                } else {
38                    match line.parse() {
39                        Ok(authorization) => KeysFileLine::Key(authorization),
40                        Err(e) => {
41                            return Err(format!(
42                                "failed to parse line {}: {}",
43                                line_no,
44                                e.to_string()
45                            ))
46                        }
47                    }
48                },
49            );
50        }
51
52        Ok(Self { lines })
53    }
54}