Skip to main content

parkour/impls/
array.rs

1use std::convert::TryInto;
2
3use crate::{Error, ErrorInner, FromInputValue};
4
5#[derive(Debug)]
6pub struct ArrayCtx<C> {
7    pub delimiter: Option<char>,
8    pub inner: C,
9}
10
11impl<C> ArrayCtx<C> {
12    pub fn new(delimiter: Option<char>, inner: C) -> Self {
13        Self { delimiter, inner }
14    }
15}
16
17impl<C: Default> Default for ArrayCtx<C> {
18    fn default() -> Self {
19        ArrayCtx { delimiter: Some(','), inner: C::default() }
20    }
21}
22
23impl<T: FromInputValue, const N: usize> FromInputValue for [T; N] {
24    type Context = ArrayCtx<T::Context>;
25
26    fn from_input_value(value: &str, context: &Self::Context) -> Result<Self, Error> {
27        if let Some(delim) = context.delimiter {
28            let values = value
29                .split(delim)
30                .map(|s| T::from_input_value(s, &context.inner))
31                .collect::<Result<Vec<T>, _>>()?;
32
33            let len = values.len();
34            match values.try_into() {
35                Ok(values) => Ok(values),
36                Err(_) => {
37                    Err(ErrorInner::WrongNumberOfValues { expected: N, got: len }.into())
38                }
39            }
40        } else {
41            Err(ErrorInner::WrongNumberOfValues { expected: N, got: 1 }.into())
42        }
43    }
44}
45
46/*
47impl<T: FromInputValue, const N: usize> FromInput for [T; N]
48where
49    T::Context: Clone,
50{
51    type Context = ArrayCtx<T::Context>;
52
53    fn from_input<P: Parse>(
54        input: &mut P,
55        context: Self::Context,
56    ) -> Result<Self, Error> {
57        if input.can_parse_value_no_whitespace() {
58            input.parse_value(context)
59        } else {
60            let mut values = Vec::<T>::new();
61
62            for _ in 0..N {
63                match input.parse_value(context.inner.clone()) {
64                    Err(Error::no_value) => break,
65                    Err(e) => return Err(e),
66                    Ok(value) => values.push(value),
67                }
68            }
69
70            let len = values.len();
71            match values.try_into() {
72                Ok(values) => Ok(values),
73                Err(_) => Err(Error::WrongNumberOfValues { expected: N, got: len }),
74            }
75        }
76    }
77}
78*/