asyncio/
from_str.rs

1use ffi::if_nametoindex;
2use error::EAFNOSUPPORT;
3use ip::{LlAddr, IpAddrV4, IpAddrV6, IpAddr};
4
5use std::io;
6use std::result;
7use std::str::{Chars, FromStr};
8use std::ffi::CString;
9
10#[derive(Debug)]
11struct ParseError;
12
13type Result<T> = result::Result<T, ParseError>;
14
15trait Parser : Clone + Copy {
16    type Output;
17    fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)>;
18}
19
20#[derive(Clone, Copy)]
21struct Lit(char);
22impl Parser for Lit {
23    type Output = ();
24
25    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
26        match it.next() {
27            Some(ch) if ch == self.0 => Ok(((), it)),
28            _ => Err(ParseError),
29        }
30    }
31}
32
33#[derive(Clone, Copy)]
34struct LitOr(char, char);
35impl Parser for LitOr {
36    type Output = ();
37
38    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)>  {
39        match it.next() {
40            Some(ch) if ch == self.0 || ch == self.1 => Ok(((), it)),
41            _ => Err(ParseError),
42        }
43    }
44}
45
46#[derive(Clone, Copy)]
47struct Char(&'static str);
48impl Parser for Char {
49    type Output = char;
50
51    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
52        if let Some(ch) = it.next() {
53            let mut a = '\0';
54            let mut chars = self.0.chars();
55            while let Some(b) = chars.next() {
56                if b == '-' {
57                    if let Some(b) = chars.next() {
58                        if a < ch && ch <= b {
59                            return Ok((ch, it))
60                        }
61                    } else if ch == '-' {
62                        return Ok((ch, it));
63                    }
64                } else if ch == b {
65                    return Ok((ch, it))
66                }
67                a = b;
68            }
69        }
70        Err(ParseError)
71    }
72}
73
74#[derive(Clone, Copy)]
75struct Dec8;
76impl Parser for Dec8 {
77    type Output = u8;
78
79    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
80        let mut n = match it.next() {
81            Some(ch) => match ch.to_digit(10) {
82                Some(i) => i,
83                _ => return Err(ParseError),
84            },
85            _ => return Err(ParseError),
86        };
87        for _ in 0..2 {
88            let p = it.clone();
89            n = match it.next() {
90                Some(ch) => match ch.to_digit(10) {
91                    Some(i) => n * 10 + i,
92                    _ => return Ok((n as u8, p))
93                },
94                _ => return Ok((n as u8, p)),
95            };
96        }
97        if n <= 255 {
98            Ok((n as u8, it))
99        } else {
100            Err(ParseError)
101        }
102    }
103}
104
105#[derive(Clone, Copy)]
106struct Hex08;
107impl Parser for Hex08 {
108    type Output = u8;
109
110    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
111        let mut n = match it.next() {
112            Some(ch) => match ch.to_digit(16) {
113                Some(i) => i,
114                _ => return Err(ParseError),
115            },
116            _ => return Err(ParseError),
117        };
118        n = match it.next() {
119            Some(ch) => match ch.to_digit(16) {
120                Some(i) => n * 16 + i,
121                _ => return Err(ParseError),
122            },
123            _ => return Err(ParseError),
124        };
125        if n <= 255 {
126            Ok((n as u8, it))
127        } else {
128            Err(ParseError)
129        }
130    }
131}
132
133#[derive(Clone, Copy)]
134struct Hex16;
135impl Parser for Hex16 {
136    type Output = u16;
137
138    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
139        let mut n = match it.next() {
140            Some(ch) => match ch.to_digit(16) {
141                Some(i) => i,
142                _ => return Err(ParseError),
143            },
144            _ => return Err(ParseError),
145        };
146        for _ in 0..4 {
147            let p = it.clone();
148            n = match it.next() {
149                Some(ch) => match ch.to_digit(16) {
150                    Some(i) => n * 16 + i,
151                    _ => return Ok((n as u16, p)),
152                },
153                _ => return Ok((n as u16, p)),
154            };
155        }
156        if n < 65536 {
157            Ok((n as u16, it))
158        } else {
159            Err(ParseError)
160        }
161    }
162}
163
164#[derive(Clone, Copy)]
165struct Cat<P1, P2>(P1, P2);
166impl<P1: Parser, P2: Parser> Parser for Cat<P1, P2> {
167    type Output = (P1::Output, P2::Output);
168
169    fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
170        if let Ok((a, it)) = self.0.parse(it) {
171            if let Ok((b, it)) = self.1.parse(it) {
172                return Ok(((a, b), it));
173            }
174        }
175        Err(ParseError)
176    }
177}
178
179#[derive(Clone, Copy)]
180struct Sep4By<P: Parser, By: Parser>(P, By);
181impl<P: Parser, By: Parser> Parser for Sep4By<P, By> {
182    type Output = [P::Output; 4];
183
184    fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
185        let (a, it) = try!(self.0.parse(it));
186        let (_, it) = try!(self.1.parse(it));
187        let (b, it) = try!(self.0.parse(it));
188        let (_, it) = try!(self.1.parse(it));
189        let (c, it) = try!(self.0.parse(it));
190        let (_, it) = try!(self.1.parse(it));
191        let (d, it) = try!(self.0.parse(it));
192        Ok(([a,b,c,d], it))
193    }
194}
195
196#[derive(Clone, Copy)]
197struct Sep6By<P, By>(P, By);
198impl<P: Parser, By: Parser> Parser for Sep6By<P, By> {
199    type Output = [P::Output; 6];
200
201    fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
202        let (a, it) = try!(self.0.parse(it));
203        let (_, it) = try!(self.1.parse(it));
204        let (b, it) = try!(self.0.parse(it));
205        let (_, it) = try!(self.1.parse(it));
206        let (c, it) = try!(self.0.parse(it));
207        let (_, it) = try!(self.1.parse(it));
208        let (d, it) = try!(self.0.parse(it));
209        let (_, it) = try!(self.1.parse(it));
210        let (e, it) = try!(self.0.parse(it));
211        let (_, it) = try!(self.1.parse(it));
212        let (f, it) = try!(self.0.parse(it));
213        Ok(([a,b,c,d,e,f], it))
214    }
215}
216
217#[derive(Clone, Copy)]
218struct SepBy<P, By>(P, By, usize);
219impl<P: Parser, By: Parser> Parser for SepBy<P, By> {
220    type Output = Vec<P::Output>;
221
222    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
223        let mut vec = Vec::new();
224
225        if let Ok((a, ne)) = self.0.parse(it.clone()) {
226            it = ne;
227            vec.push(a);
228
229            while vec.len() < self.2 {
230                if let Ok(((_, a), ne)) = Cat(self.1, self.0).parse(it.clone()) {
231                    it = ne;
232                    vec.push(a);
233                } else {
234                    break;
235                }
236            }
237        }
238        Ok((vec, it))
239    }
240}
241
242#[derive(Clone, Copy)]
243struct Between<A, P, B>(A, P, B);
244impl<A: Parser, P: Parser, B: Parser> Parser for Between<A, P, B> {
245    type Output = P::Output;
246
247    fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
248        let (_, it) = try!(self.0.parse(it));
249        let (a, it) = try!(self.1.parse(it));
250        let (_, it) = try!(self.2.parse(it));
251        Ok((a, it))
252    }
253}
254
255#[derive(Clone, Copy)]
256struct Eos<P>(P);
257impl<P: Parser> Parser for Eos<P> {
258    type Output = P::Output;
259
260    fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
261        let (a, mut it) = try!(self.0.parse(it));
262        if let Some(_) = it.next() {
263            return Err(ParseError);
264        }
265        Ok((a, it))
266    }
267}
268
269fn hex16_to_dec8(mut hex: u16) -> Option<u8> {
270    let d = hex % 16;
271    if d >= 10 { return None; }
272    hex /= 16;
273    let c = hex % 16;
274    if c >= 10 { return None; }
275    hex /= 16;
276    let b = hex % 16;
277    if b >= 10 { return None; }
278    hex /= 16;
279    let a = hex % 16;
280    if a >= 10 { return None; }
281    Some((((a * 10 + b) * 10 + c) * 10 + d) as u8)
282}
283
284#[derive(Clone, Copy)]
285struct IpV6;
286impl Parser for IpV6 {
287    type Output = [u16; 8];
288
289    fn parse<'a>(&self, mut it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
290        fn parse_ipv4<'a>(mut ar: [u16; 8], it: Chars<'a>) -> Result<([u16; 8], Chars<'a>)> {
291            if ar[0] == 0 && ar[1] == 0 && ar[2] == 0 && ar[3] == 0 && ar[4] == 0
292                && (ar[5] == 0 && ar[6] == 0 ||
293                    ar[5] == 65535 && ar[6] == 0 ||
294                    ar[5] == 0 && ar[6] == 65535)
295            {
296                if let Some(a) = hex16_to_dec8(ar[7]) {
297                    if let Ok(((_, b), ne)) = Cat(Lit('.'), Dec8).parse(it.clone()) {
298                        if let Ok(((_, c), ne)) = Cat(Lit('.'), Dec8).parse(ne) {
299                            if let Ok(((_, d), ne)) = Cat(Lit('.'), Dec8).parse(ne) {
300                                if ar[6] == 0xFFFF {
301                                    ar[5] = 0xFFFF;
302                                }
303                                ar[6] = (a as u16 * 256) | b as u16;
304                                ar[7] = (c as u16 * 256) | d as u16;
305                                return Ok((ar, ne));
306                            }
307                        }
308                    }
309                }
310            }
311            Ok((ar, it))
312        }
313
314        fn parse_rev<'a>(mut ar: [u16; 8], i: usize, it: Chars<'a>) -> Result<([u16; 8], Chars<'a>)> {
315            if let Ok((seps, it)) = SepBy(Hex16, Lit(':'), 7-i).parse(it.clone()) {
316                for (i, hex) in seps.iter().rev().enumerate() {
317                    ar[7-i] = *hex;
318                }
319                return parse_ipv4(ar, it);
320            }
321
322            Err(ParseError)
323        }
324
325        let mut ar = [0; 8];
326        for i in 0..7 {
327            if let Ok((_, it)) = Cat(Lit(':'), Lit(':')).parse(it.clone()) {
328                return parse_rev(ar, i, it);
329            } else if let Ok(((hex, _), ne)) = Cat(Hex16, Lit(':')).parse(it.clone()) {
330                ar[i] = hex;
331                it = ne;
332                if let Ok((_, it)) = Lit(':').parse(it.clone()) {
333                    return parse_rev(ar, i, it);
334                }
335            } else {
336                return parse_rev(ar, i, it);
337            }
338        }
339
340        if let Ok((hex, it)) = Hex16.parse(it.clone()) {
341            ar[7] = hex;
342            Ok((ar, it))
343        } else if let Ok((_, it)) = Lit(':').parse(it) {
344            Ok((ar, it))
345        } else {
346            Err(ParseError)
347        }
348    }
349}
350
351#[derive(Clone, Copy)]
352struct ScopeId;
353impl Parser for ScopeId {
354    type Output = u32;
355
356    fn parse<'a>(&self, it: Chars<'a>) -> Result<(Self::Output, Chars<'a>)> {
357        if let Ok((_, it)) = Lit('%').parse(it.clone()) {
358            if let Ok((ch, mut it)) = Char("a-zA-Z").parse(it.clone()) {
359                let mut vec: Vec<u8> = Vec::new();
360                vec.push(ch as u8);
361                while let Ok((ch, ne)) = Char("0-9a-zA-Z.:_-").parse(it.clone()) {
362                    vec.push(ch as u8);
363                    it = ne;
364                }
365                let name = unsafe { CString::from_vec_unchecked(vec) };
366                if let Ok(id) = if_nametoindex(&name) {
367                    return Ok((id, it));
368                }
369            }
370            if let Ok((dec, it)) = Dec8.parse(it.clone()) {
371                return Ok((dec as u32, it));
372            }
373        }
374        Ok((0, it))
375    }
376}
377
378impl FromStr for LlAddr {
379    type Err = io::Error;
380
381    fn from_str(s: &str) -> io::Result<LlAddr> {
382        if let Ok((addr, _)) = Eos(Sep6By(Hex08, LitOr('-', ':'))).parse(s.chars()) {
383            Ok(LlAddr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]))
384        } else {
385            Err(EAFNOSUPPORT.into())
386        }
387    }
388}
389
390impl FromStr for IpAddrV4 {
391    type Err = io::Error;
392
393    fn from_str(s: &str) -> io::Result<IpAddrV4> {
394        if let Ok((addr, _)) = Eos(Sep4By(Dec8, Lit('.'))).parse(s.chars()) {
395            Ok(IpAddrV4::new(addr[0], addr[1], addr[2], addr[3]))
396        } else {
397            Err(EAFNOSUPPORT.into())
398        }
399    }
400}
401
402impl FromStr for IpAddrV6 {
403    type Err = io::Error;
404
405    fn from_str(s: &str) -> io::Result<IpAddrV6> {
406        if let Ok(((addr, id), _)) = Eos(Cat(IpV6, ScopeId)).parse(s.chars()) {
407            Ok(IpAddrV6::with_scope_id(addr[0], addr[1], addr[2], addr[3],
408                                       addr[4], addr[5], addr[6], addr[7], id))
409        } else {
410            Err(EAFNOSUPPORT.into())
411        }
412    }
413}
414
415impl FromStr for IpAddr {
416    type Err = io::Error;
417
418    fn from_str(s: &str) -> io::Result<IpAddr> {
419        match IpAddrV4::from_str(s) {
420            Ok(v4) => Ok(IpAddr::V4(v4)),
421            Err(_) =>  match IpAddrV6::from_str(s) {
422                Ok(v6) => Ok(IpAddr::V6(v6)),
423                Err(err) => Err(err),
424            }
425        }
426    }
427}
428
429#[test]
430fn test_lit() {
431    assert_eq!(Lit('.').parse(".0".chars()).unwrap().0, ());
432    assert_eq!(Lit(':').parse(":1".chars()).unwrap().0, ());
433}
434
435#[test]
436fn test_lit_or() {
437    assert_eq!(LitOr(':', '-').parse("-1".chars()).unwrap().0, ());
438    assert_eq!(LitOr(':', '-').parse(":2".chars()).unwrap().0, ());
439}
440
441#[test]
442fn test_char() {
443    assert_eq!(Char("abc").parse("a".chars()).unwrap().0, 'a');
444    assert_eq!(Char("abc").parse("b".chars()).unwrap().0, 'b');
445    assert_eq!(Char("a-z").parse("z".chars()).unwrap().0, 'z');
446    assert_eq!(Char("a-f0-9").parse("4".chars()).unwrap().0, '4');
447    assert_eq!(Char("0-0A-Za-z-").parse("-".chars()).unwrap().0, '-');
448    assert!(Char("abc").parse("d".chars()).is_err());
449}
450
451#[test]
452fn test_dec8() {
453    let p = Dec8;
454    assert_eq!(p.parse("0".chars()).unwrap().0, 0);
455    assert_eq!(p.parse("010".chars()).unwrap().0, 10);
456    assert_eq!(p.parse("123".chars()).unwrap().0, 123);
457    assert_eq!(p.parse("255".chars()).unwrap().0, 255);
458    assert!(p.parse("256".chars()).is_err());
459}
460
461#[test]
462fn test_hex08() {
463    let p = Hex08;
464    assert_eq!(p.parse("00".chars()).unwrap().0, 0);
465    assert_eq!(p.parse("10".chars()).unwrap().0, 16);
466    assert_eq!(p.parse("fF".chars()).unwrap().0, 255);
467    assert!(p.parse("0".chars()).is_err());
468    assert!(p.parse("f".chars()).is_err());
469    assert!(p.parse("-1".chars()).is_err());
470    assert!(p.parse("GF".chars()).is_err());
471}
472
473#[test]
474fn test_hex16() {
475    let p = Hex16;
476    assert_eq!(p.parse("0".chars()).unwrap().0, 0);
477    assert_eq!(p.parse("f".chars()).unwrap().0, 15);
478    assert_eq!(p.parse("10".chars()).unwrap().0, 16);
479    assert_eq!(p.parse("fF".chars()).unwrap().0, 255);
480    assert_eq!(p.parse("FfFf".chars()).unwrap().0, 65535);
481    assert!(p.parse("-1".chars()).is_err());
482    assert!(p.parse("GF".chars()).is_err());
483}
484
485#[test]
486fn test_cat() {
487    let p = Cat(Hex16, Lit(':'));
488    assert_eq!((p.parse("0:".chars()).unwrap().0).0, 0);
489    assert!((p.parse("0-".chars()).is_err()));
490    assert_eq!((p.parse("10:".chars()).unwrap().0).0, 16);
491    assert_eq!((p.parse("ff:".chars()).unwrap().0).0, 255);
492    assert_eq!((p.parse("ffff:".chars()).unwrap().0).0, 65535);
493    assert!((p.parse("fffff:".chars()).is_err()));
494}
495
496#[test]
497fn test_lladdr() {
498    assert_eq!(LlAddr::from_str("00:00:00:00:00:00").unwrap(), LlAddr::new(0,0,0,0,0,0));
499    assert_eq!(LlAddr::from_str("FF:ff:FF:fF:Ff:ff").unwrap(), LlAddr::new(255,255,255,255,255,255));
500}
501
502#[test]
503fn test_ipv6() {
504    let p = IpV6;
505    assert_eq!(p.parse("1:2:3:4:5:6:7:8".chars()).unwrap().0, [1,2,3,4,5,6,7,8]);
506    assert_eq!(p.parse("::".chars()).unwrap().0, [0;8]);
507    assert_eq!(p.parse("::1".chars()).unwrap().0, [0,0,0,0,0,0,0,1]);
508    assert_eq!(p.parse("::ffff:1".chars()).unwrap().0, [0,0,0,0,0,0,0xFFFF,1]);
509    assert_eq!(p.parse("::2:3:4:5:6:7:8".chars()).unwrap().0, [0,2,3,4,5,6,7,8]);
510    assert_eq!(p.parse("1::".chars()).unwrap().0, [1,0,0,0,0,0,0,0]);
511    assert_eq!(p.parse("1::8".chars()).unwrap().0, [1,0,0,0,0,0,0,8]);
512    assert_eq!(p.parse("1:2::8".chars()).unwrap().0, [1,2,0,0,0,0,0,8]);
513    assert_eq!(p.parse("1::7:8".chars()).unwrap().0, [1,0,0,0,0,0,7,8]);
514    assert_eq!(p.parse("1:2:3:4:5:6:7::".chars()).unwrap().0, [1,2,3,4,5,6,7,0]);
515    assert_eq!(p.parse("0:0:0:0:0:0:255.255.255.255".chars()).unwrap().0, [0,0,0,0,0,0,0xFFFF,0xFFFF]);
516    assert_eq!(p.parse("::0.255.255.0".chars()).unwrap().0, [0,0,0,0,0,0,0xFF,0xFF00]);
517    assert_eq!(p.parse("0:0:0:0:0:FFFF:255.255.255.255".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFFFF,0xFFFF]);
518    assert_eq!(p.parse("::FFFF:0.255.255.0".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFF,0xFF00]);
519    assert_eq!(p.parse("1:2:3:4:5:6:7:8:9".chars()).unwrap().0, [1,2,3,4,5,6,7,8]);
520    assert_eq!(p.parse("::2:3:4:5:6:7:8:9".chars()).unwrap().0, [0,2,3,4,5,6,7,8]);
521    assert_eq!(p.parse("::2:3:4:5:6:7:8:9".chars()).unwrap().0, [0,2,3,4,5,6,7,8]);
522    assert_eq!(p.parse("0:0:0:0:0:0:255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0,0xFF00,0xFF]);
523    assert_eq!(p.parse("::255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0,0xFF00,0xFF]);
524    assert_eq!(p.parse("0:0:0:0:0:ffff:255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFF00,0xFF]);
525    assert_eq!(p.parse("::ffff:255.0.0.255.255".chars()).unwrap().0, [0,0,0,0,0,0xFFFF,0xFF00,0xFF]);
526}
527
528#[test]
529fn test_ipaddr_v4() {
530    assert_eq!(IpAddrV4::from_str("0.0.0.0").unwrap(), IpAddrV4::new(0,0,0,0));
531    assert_eq!(IpAddrV4::from_str("1.2.3.4").unwrap(), IpAddrV4::new(1,2,3,4));
532}
533
534#[test]
535fn test_ipaddr_v6() {
536    assert_eq!(IpAddrV6::from_str("1:2:3:4:5:6:7:8").unwrap(), IpAddrV6::new(1,2,3,4,5,6,7,8));
537    assert!(IpAddrV6::from_str("1:2:3:4:5:6:7:8:9").is_err());
538    assert_eq!(IpAddrV6::from_str("::").unwrap(), IpAddrV6::any());
539    assert_eq!(IpAddrV6::from_str("::192.168.0.1").unwrap(), IpAddrV6::v4_compatible(&IpAddrV4::new(192,168,0,1)).unwrap());
540    assert!(IpAddrV6::from_str("::192.168.0.1.1").is_err());
541    assert_eq!(IpAddrV6::from_str("::ffff:0.0.0.0").unwrap(), IpAddrV6::v4_mapped(&IpAddrV4::any()));
542    assert!(IpAddrV6::from_str("::1:192.168.0.1").is_err());
543    assert_eq!(IpAddrV6::from_str("1:2:3:4:5:6:7:8%10").unwrap(), IpAddrV6::with_scope_id(1,2,3,4,5,6,7,8, 10));
544
545    if cfg!(target_os = "linux") {
546        assert!(IpAddrV6::from_str("1:2:3:4:5:6:7:8%lo").unwrap().get_scope_id() != 0);
547    } else if cfg!(windows) {
548        // TODO
549    } else {
550        assert!(IpAddrV6::from_str("1:2:3:4:5:6:7:8%lo0").unwrap().get_scope_id() != 0);
551    }
552}
553
554#[test]
555fn test_ipaddr() {
556    assert_eq!(IpAddr::from_str("0.0.0.0").unwrap(), IpAddr::V4(IpAddrV4::new(0,0,0,0)));
557    assert_eq!(IpAddr::from_str("1.2.3.4").unwrap(), IpAddr::V4(IpAddrV4::new(1,2,3,4)));
558    assert_eq!(IpAddr::from_str("1:2:3:4:5:6:7:8").unwrap(), IpAddr::V6(IpAddrV6::new(1,2,3,4,5,6,7,8)));
559    assert_eq!(IpAddr::from_str("::").unwrap(), IpAddr::V6(IpAddrV6::any()));
560    assert_eq!(IpAddr::from_str("::192.168.0.1").unwrap(), IpAddr::V6(IpAddrV6::v4_compatible(&IpAddrV4::new(192,168,0,1)).unwrap()));
561}