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*/