gettext_utils/
lib.rs

1#[derive(Debug)]
2#[doc(hidden)]
3pub enum FormatError {
4    UnmatchedCurlyBracket,
5    InvalidPositionalArgument,
6}
7
8#[doc(hidden)]
9pub fn try_format<'a>(
10    str_pattern: &'a str,
11    argv: &[::std::boxed::Box<dyn ::std::fmt::Display + 'a>],
12) -> ::std::result::Result<::std::string::String, FormatError> {
13    use ::std::fmt::Write;
14    use ::std::iter::Iterator;
15
16    //first we parse the pattern
17    let mut pattern = vec![];
18    let mut vars = vec![];
19    let mut finish_or_fail = false;
20    for (i, part) in str_pattern.split('}').enumerate() {
21        if finish_or_fail {
22            return ::std::result::Result::Err(FormatError::UnmatchedCurlyBracket);
23        }
24        if part.contains('{') {
25            let mut part = part.split('{');
26            let text = part.next().unwrap();
27            let arg = part.next().ok_or(FormatError::UnmatchedCurlyBracket)?;
28            if part.next() != ::std::option::Option::None {
29                return ::std::result::Result::Err(FormatError::UnmatchedCurlyBracket);
30            }
31            pattern.push(text);
32            vars.push(
33                argv.get::<usize>(if arg.len() > 0 {
34                    arg.parse()
35                        .map_err(|_| FormatError::InvalidPositionalArgument)?
36                } else {
37                    i
38                })
39                .ok_or(FormatError::InvalidPositionalArgument)?,
40            );
41        } else {
42            finish_or_fail = true;
43            pattern.push(part);
44        }
45    }
46
47    //then we generate the result String
48    let mut res = ::std::string::String::with_capacity(str_pattern.len());
49    let mut pattern = pattern.iter();
50    let mut vars = vars.iter();
51    while let ::std::option::Option::Some(text) = pattern.next() {
52        res.write_str(text).unwrap();
53        if let ::std::option::Option::Some(var) = vars.next() {
54            res.write_str(&format!("{}", var)).unwrap();
55        }
56    }
57    ::std::result::Result::Ok(res)
58}
59