1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
use crate::parser::errors::ParserError; pub fn parse_language_subtag(subtag: &str) -> Result<Option<String>, ParserError> { let slen = subtag.len(); if slen < 2 || slen > 8 || slen == 4 || subtag.contains(|c: char| !c.is_ascii_alphabetic()) { return Err(ParserError::InvalidLanguage); } let value = subtag.to_ascii_lowercase(); if value == "und" { Ok(None) } else { Ok(Some(value)) } } pub fn parse_script_subtag(subtag: &str) -> Result<String, ParserError> { let slen = subtag.len(); if slen != 4 || subtag.contains(|c: char| !c.is_ascii_alphabetic()) { return Err(ParserError::InvalidSubtag); } let mut result = subtag.to_ascii_lowercase(); result[0..1].make_ascii_uppercase(); Ok(result) } pub fn parse_region_subtag(subtag: &str) -> Result<String, ParserError> { let slen = subtag.len(); if slen == 2 && !subtag.contains(|c: char| !c.is_ascii_alphabetic()) || slen == 3 && !subtag.contains(|c: char| !c.is_ascii_digit()) { Ok(subtag.to_ascii_uppercase()) } else { Err(ParserError::InvalidSubtag) } } pub fn parse_variant_subtag(subtag: &str) -> Result<String, ParserError> { let slen = subtag.len(); if slen < 4 || slen > 8 { return Err(ParserError::InvalidSubtag); } if slen >= 5 && subtag.contains(|c: char| !c.is_ascii_alphanumeric()) { return Err(ParserError::InvalidSubtag); } if slen == 4 && !subtag.as_bytes()[0].is_ascii_digit() && subtag[1..].contains(|c: char| !c.is_ascii_alphanumeric()) { return Err(ParserError::InvalidSubtag); } Ok(subtag.to_ascii_lowercase()) }