use std::borrow::Cow;
use crate::Tags;
pub fn parse_badges(input: &str) -> impl Iterator<Item = Badge<'_>> + '_ {
input
.split(',')
.flat_map(|badge| badge.split_once('/'))
.map(|(name, version)| {
let mut version = Cow::from(version);
Badge::unescape(&mut version);
Badge {
name: Cow::from(name),
version,
}
})
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
pub struct Badge<'a> {
pub name: Cow<'a, str>,
pub version: Cow<'a, str>,
}
impl<'a> Badge<'a> {
pub fn from_tags<'t: 'a>(tags: &'t Tags<'a>) -> impl Iterator<Item = Badge<'a>> + 't {
tags.get("badges").into_iter().flat_map(parse_badges)
}
}
pub type BadgeInfo<'a> = Badge<'a>;
impl Badge<'_> {
fn unescape(s: &mut Cow<'_, str>) {
const ESCAPED: [char; 1] = ['⸝'];
const REPLACEMENTS: [char; 1] = [','];
if !s.chars().any(|c| ESCAPED.contains(&c)) {
return;
}
*s = s
.chars()
.map(|c| {
if let Some(p) = ESCAPED.iter().position(|&s| s == c) {
REPLACEMENTS[p]
} else {
c
}
})
.collect::<String>()
.into();
}
}