From ff71924d5d7447cbb847aab2e72cd5a1b682f425 Mon Sep 17 00:00:00 2001 From: Nordine Bittich Date: Mon, 25 Nov 2024 00:46:51 +0100 Subject: [PATCH] parse ip: cleanup --- src/iri.rs | 145 +++++++++++++++++++-------------------- src/turtle/turtle_doc.rs | 5 ++ 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/iri.rs b/src/iri.rs index 73d24db..9376ab0 100644 --- a/src/iri.rs +++ b/src/iri.rs @@ -1,91 +1,86 @@ -#![allow(unused)] - -use std::{collections::VecDeque, ops::RangeBounds}; - -use chrono::ParseResult; -use nom::{ - bytes::complete::take_while_m_n, - character::complete::one_of, - combinator::{success, verify}, - error::{ParseError, VerboseError}, - multi::{many1, many_m_n}, -}; - -use crate::prelude::*; - -pub enum Segment { - Hextet(u16), - Compressed, - IpV4(Vec), -} -fn parse_ip_v6(s: &str) -> ParserResult> { - fn hex_to_u16(input: &str) -> Result { - u16::from_str_radix(input, 16) - } - fn recognize_hexadecimal(input: &str) -> ParserResult<&str> { - recognize(take_while_m_n(1, 4, |c: char| c.is_ascii_hexdigit()))(input) - } - fn hextet(s: &str) -> ParserResult { - map_res(recognize_hexadecimal, hex_to_u16)(s) +#[allow(unused)] +mod ip { + use nom::{ + bytes::complete::take_while_m_n, + combinator::verify, + error::{ParseError, VerboseError}, + multi::many_m_n, }; - fn segment(s: &str) -> ParserResult { - alt(( - map(tag("::"), |_| Segment::Compressed), - preceded(opt(tag(":")), map(parse_ip_v4, Segment::IpV4)), - preceded(opt(tag(":")), map(hextet, Segment::Hextet)), - ))(s) + + use crate::prelude::*; + enum Segment { + Hextet(u16), + Compressed, + IpV4(Vec), } - let mut ipv6: Vec = vec![]; - let (rest, list) = verify(many_m_n(1, 8, segment), |l: &[Segment]| { - l.iter() - .filter(|seg| matches!(seg, Segment::Compressed)) - .count() - <= 1 - && l.iter() - .filter(|seg| matches!(seg, Segment::IpV4(_))) + pub(super) fn parse_ip_v6(s: &str) -> ParserResult> { + fn hex_to_u16(input: &str) -> Result { + u16::from_str_radix(input, 16) + } + fn recognize_hexadecimal(input: &str) -> ParserResult<&str> { + recognize(take_while_m_n(1, 4, |c: char| c.is_ascii_hexdigit()))(input) + } + fn hextet(s: &str) -> ParserResult { + map_res(recognize_hexadecimal, hex_to_u16)(s) + } + fn segment(s: &str) -> ParserResult { + alt(( + map(tag("::"), |_| Segment::Compressed), + preceded(opt(tag(":")), map(parse_ip_v4, Segment::IpV4)), + preceded(opt(tag(":")), map(hextet, Segment::Hextet)), + ))(s) + } + let mut ipv6: Vec = vec![]; + let (rest, list) = verify(many_m_n(1, 8, segment), |l: &[Segment]| { + l.iter() + .filter(|seg| matches!(seg, Segment::Compressed)) .count() <= 1 - })(s)?; + && l.iter() + .filter(|seg| matches!(seg, Segment::IpV4(_))) + .count() + <= 1 + })(s)?; - let mut compression_pos = None; - for (idx, segment) in list.into_iter().enumerate() { - match segment { - Segment::Hextet(v) => ipv6.push(v), - Segment::Compressed => { - compression_pos = Some(idx); - } - Segment::IpV4(_) if idx == 0 => { - let err = VerboseError::from_error_kind(s, ErrorKind::IsNot); - return Err(nom::Err::Error(err)); + let mut compression_pos = None; + for (idx, segment) in list.into_iter().enumerate() { + match segment { + Segment::Hextet(v) => ipv6.push(v), + Segment::Compressed => { + compression_pos = Some(idx); + } + Segment::IpV4(_) if idx == 0 => { + let err = VerboseError::from_error_kind(s, ErrorKind::IsNot); + return Err(nom::Err::Error(err)); + } + Segment::IpV4(l) => { + ipv6.push((l[0] as u16) << 8 | l[1] as u16); + ipv6.push((l[2] as u16) << 8 | l[3] as u16); + } } - Segment::IpV4(l) => { - ipv6.push((l[0] as u16) << 8 | l[1] as u16); - ipv6.push((l[2] as u16) << 8 | l[3] as u16); + } + if let Some(idx) = compression_pos { + while ipv6.len() < 8 { + ipv6.insert(idx, 0x0); } } + + Ok((rest, ipv6)) } - if let Some(idx) = compression_pos { - let len = ipv6.len(); - while ipv6.len() < 8 { - ipv6.insert(idx, 0x0); - } + pub(super) fn parse_ip_v4(s: &str) -> ParserResult> { + verify( + separated_list1( + tag("."), + map_parser(take_while1(|c: char| c.is_numeric()), all_consuming(U8)), + ), + |list: &[u8]| list.len() == 4, + )(s) } - - Ok((rest, ipv6)) -} -fn parse_ip_v4(s: &str) -> ParserResult> { - verify( - separated_list1( - tag("."), - map_parser(take_while1(|c: char| c.is_numeric()), all_consuming(U8)), - ), - |list: &[u8]| list.len() == 4, - )(s) } - #[cfg(test)] + mod test { - use crate::iri::{parse_ip_v4, parse_ip_v6}; + use crate::iri::ip::{parse_ip_v4, parse_ip_v6}; #[test] fn parse_ip_v4_test() { diff --git a/src/turtle/turtle_doc.rs b/src/turtle/turtle_doc.rs index 048b6b7..25f1f8d 100644 --- a/src/turtle/turtle_doc.rs +++ b/src/turtle/turtle_doc.rs @@ -185,6 +185,11 @@ impl<'a> TurtleDoc<'a> { .into_iter() .map(|(k, v)| (Cow::Owned(k), Cow::Owned(v))) .collect(); + // for (k, prefix) in prefixes { + // if self.prefixes.contains_key(&k) { + // panic("FIXME. https://www.ietf.org/rfc/rfc3987.html"); + // } + // } self.prefixes.extend(prefixes); } pub fn len(&self) -> usize {