diff --git a/src/attribute.rs b/src/attribute.rs index a7eca8a..c48a6e5 100644 --- a/src/attribute.rs +++ b/src/attribute.rs @@ -215,9 +215,14 @@ impl<'a> Value<'a> { } fn validate(value: &str) -> Result<(), InvalidValueError> { - if value.chars().any(|c| !matches!(c, '\u{0000}'..='\u{00FF}')) { + value.chars().try_for_each(Self::validate_char) + } + + #[inline] + pub(crate) fn validate_char(c: char) -> Result<(), InvalidValueError> { + if !is_extended_ascii(c) { return Err(InvalidValueError::NonExtendedAscii); - } else if value.chars().any(|c| c.is_ascii_control()) { + } else if c.is_ascii_control() { return Err(InvalidValueError::ContainsControlChar); } @@ -413,6 +418,12 @@ where } } +/// Checks if the given char is part of the extended ASCII set. +#[inline] +fn is_extended_ascii(char: char) -> bool { + matches!(char, '\u{0000}'..='\u{00FF}') +} + #[cfg(test)] mod tests { use proptest::prelude::*; diff --git a/src/parser/component.rs b/src/parser/component.rs index 1dfc1dd..882eac2 100644 --- a/src/parser/component.rs +++ b/src/parser/component.rs @@ -7,7 +7,7 @@ use winnow::{ PResult, Parser, }; -use crate::Attribute; +use crate::{Attribute, Value}; // A response code or message sent by the whois server. // Starts with the "%" character and extends until the end of the line. @@ -56,10 +56,7 @@ pub fn attribute_name<'s>(input: &mut &'s str) -> PResult<&'s str> { // An extended ASCII sequence of characters, excluding control. pub fn attribute_value<'s>(input: &mut &'s str) -> PResult<&'s str> { - take_while(0.., |c: char| { - matches!(c, '\u{0000}'..='\u{00FF}') && !c.is_ascii_control() - }) - .parse_next(input) + take_while(0.., |c| Value::validate_char(c).is_ok()).parse_next(input) } // Extends an attributes value over multiple lines.