use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::fmt;
use crate::validate::{is_valid_language_tag, trim_ows};
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ContentLanguageError {
Empty,
InvalidFormat,
InvalidLanguageTag,
}
impl fmt::Display for ContentLanguageError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ContentLanguageError::Empty => write!(f, "empty Content-Language"),
ContentLanguageError::InvalidFormat => {
write!(f, "invalid Content-Language format")
}
ContentLanguageError::InvalidLanguageTag => {
write!(f, "invalid language tag")
}
}
}
}
impl core::error::Error for ContentLanguageError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContentLanguage {
tags: Vec<String>,
}
impl ContentLanguage {
pub fn parse(input: &str) -> Result<Self, ContentLanguageError> {
let input = trim_ows(input);
let mut tags = Vec::new();
for part in input.split(',') {
let tag = trim_ows(part);
if tag.is_empty() {
continue;
}
if !is_valid_language_tag(tag) {
return Err(ContentLanguageError::InvalidLanguageTag);
}
tags.push(tag.to_string());
}
Ok(ContentLanguage { tags })
}
pub fn tags(&self) -> &[String] {
&self.tags
}
}
impl fmt::Display for ContentLanguage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.tags.join(", "))
}
}