scan_rules/scanner/std/
mod.rs

1/*
2Copyright ⓒ 2016 Daniel Keep.
3
4Licensed under the MIT license (see LICENSE or <http://opensource.org
5/licenses/MIT>) or the Apache License, Version 2.0 (see LICENSE of
6<http://www.apache.org/licenses/LICENSE-2.0>), at your option. All
7files in the project carrying such notice may not be copied, modified,
8or distributed except according to those terms.
9*/
10/*!
11Scanner implementations for standard library (and other "official" crates) types.
12*/
13pub use self::time::Iso8601Duration;
14
15mod collections;
16mod net;
17mod time;
18
19use std::ops::{Range, RangeFrom, RangeFull, RangeTo};
20use ::ScanError;
21use ::input::ScanInput;
22use ::scanner::ScanFromStr;
23use ::util::StrUtil;
24
25macro_rules! impl_tuple {
26    () => {};
27
28    ($head:ident $($tail:ident)*) => {
29        impl<'a, $head $(, $tail)*> ::scanner::ScanFromStr<'a> for ($head, $($tail,)*)
30        where $head: ::scanner::ScanFromStr<'a>, $($tail: ::scanner::ScanFromStr<'a>,)* {
31            type Output = (<$head as ::scanner::ScanFromStr<'a>>::Output, $(<$tail as ::scanner::ScanFromStr<'a>>::Output,)*);
32            fn scan_from<I: $crate::input::ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ::ScanError> {
33                #![allow(non_snake_case)]
34                use ::util::StrUtil;
35                let s = s.as_str();
36                scan!(s;
37                    ("(", let $head: $head, $(",", let $tail: $tail,)* [","]?, ")", ..tail)
38                    => (($head, $($tail,)*), s.subslice_offset_stable(tail).unwrap())
39                )
40            }
41        }
42
43        impl_tuple! { $($tail)* }
44    };
45}
46
47#[cfg(not(feature="tuples-16"))]
48mod impl_tuples {
49    impl_tuple! { T0 T1 T2 T3 }
50}
51
52#[cfg(feature="tuples-16")]
53mod impl_tuples {
54    impl_tuple! { T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 }
55}
56
57impl<'a> ScanFromStr<'a> for () {
58    type Output = Self;
59    fn scan_from<I: ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ScanError> {
60        let s = s.as_str();
61        scan!(s; ("(", ")", ..tail) => ((), s.subslice_offset_stable(tail).unwrap()))
62    }
63}
64
65macro_rules! impl_array {
66    (@as_item $i:item) => { $i };
67    (@replace.expr $_tt:tt $sub:expr) => { $sub };
68
69    () => {};
70
71    ($len:tt $e0:ident $($ns:tt $es:ident)*) => {
72        impl_array! {
73            @as_item
74            impl<'a, T> ::scanner::ScanFromStr<'a> for [T; $len] where T: ::scanner::ScanFromStr<'a> {
75                type Output = [T::Output; $len];
76                fn scan_from<I: $crate::input::ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ::ScanError> {
77                    use ::util::StrUtil;
78                    let s = s.as_str();
79                    scan!(s;
80                        ("[", let $e0: T, $(",", let $es: T,)* [","]?, "]", ..tail)
81                        => ([$e0, $($es,)*], s.subslice_offset_stable(tail).unwrap())
82                    )
83                }
84            }
85        }
86
87        impl_array! { $($ns $es)* }
88    };
89}
90
91#[cfg(not(feature="arrays-32"))]
92mod impl_arrays {
93    impl_array! {
94        8 e8 7 e7 6 e6 5 e5 4 e4 3 e3 2 e2 1 e1
95    }
96}
97
98#[cfg(feature="arrays-32")]
99mod impl_arrays {
100    impl_array! {
101        32 e32 31 e31
102        30 e30 29 e29 28 e28 27 e27 26 e26 25 e25 24 e24 23 e23 22 e22 21 e21
103        20 e20 19 e19 18 e18 17 e17 16 e16 15 e15 14 e14 13 e13 12 e12 11 e11
104        10 e10 9 e9 8 e8 7 e7 6 e6 5 e5 4 e4 3 e3 2 e2 1 e1
105    }
106}
107
108impl<'a, T> ScanFromStr<'a> for [T; 0] {
109    type Output = Self;
110    fn scan_from<I: ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ScanError> {
111        let s = s.as_str();
112        scan!(s; ("[", "]", ..tail) => ([], s.subslice_offset_stable(tail).unwrap()))
113    }
114}
115
116impl<'a, T> ScanFromStr<'a> for Option<T> where T: ScanFromStr<'a> {
117    type Output = Option<T::Output>;
118    fn scan_from<I: ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ScanError> {
119        scan!( s.to_cursor();
120            ("Some", "(", let v: T, ")", ..tail) => (Some(v), tail),
121            ("None", ..tail) => (None, tail),
122        ).map(|(v, t)| (v, s.as_str().subslice_offset_stable(t).unwrap()))
123    }
124}
125
126impl<'a, T, E> ScanFromStr<'a> for Result<T, E>
127where T: ScanFromStr<'a>, E: ScanFromStr<'a> {
128    type Output = Result<T::Output, E::Output>;
129    fn scan_from<I: ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ScanError> {
130        scan!( s.to_cursor();
131            ("Some", "(", let v: T, ")", ..tail) => (Ok(v), tail),
132            ("Err", "(", let v: E, ")", ..tail) => (Err(v), tail),
133        ).map(|(v, t)| (v, s.as_str().subslice_offset_stable(t).unwrap()))
134    }
135}
136
137impl<'a> ScanFromStr<'a> for String {
138    type Output = Self;
139    fn scan_from<I: ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ScanError> {
140        ::scanner::QuotedString::scan_from(s)
141    }
142}
143
144scanner! { impl<'a, T> ScanFromStr for Range<T> => Range {
145    (let a: T, "..", let b: T, ..tail) => (a..b, tail)
146}}
147
148scanner! { impl<'a, T> ScanFromStr for RangeFrom<T> => RangeFrom {
149    (let a: T, "..", ..tail) => (a.., tail)
150}}
151
152scanner! { impl<'a, T> ScanFromStr for RangeTo<T> => RangeTo {
153    ("..", let b: T, ..tail) => (..b, tail)
154}}
155
156impl<'a> ScanFromStr<'a> for RangeFull {
157    type Output = Self;
158
159    fn scan_from<I: ScanInput<'a>>(s: I) -> Result<(Self::Output, usize), ScanError> {
160        use ::input::ScanCursor;
161        scan! { s.to_cursor();
162            ("..", ^..tail) => (.., tail.offset())
163        }
164    }
165}