use alloc::{borrow::Cow, string::String, vec::Vec};
use crate::{
daku::{Daku, Read as _, Write as _},
name::{Name, Read as _, Write as _},
parse::{Reader, Writer},
producers::{Producer, Read as _, Write as _},
};
#[derive(Ord, PartialOrd, Eq, PartialEq)]
#[repr(u8)]
pub(crate) enum SectionKind {
Name = 0,
Producers = 1,
Daku = 2,
Unknown,
}
#[derive(Debug)]
pub enum Section<'a> {
Name(Vec<Name<'a>>),
Producers(Vec<Producer<'a>>),
Daku(Daku<'a>),
Any {
name: Cow<'a, str>,
data: Cow<'a, [u8]>,
},
}
impl Section<'_> {
pub fn name(&self) -> &str {
use Section::*;
match self {
Name(_) => "name",
Producers(_) => "producers",
Daku(_) => "daku",
Any { name, .. } => name,
}
}
pub fn to_any(&mut self) -> Option<(&str, &[u8])> {
let (name, mut data) = (String::new(), Vec::new());
let writer = &mut Writer::new(&mut data);
match self {
Self::Name(names) => {
writer.names(names)?;
*self = Self::Any {
name: name.into(),
data: data.into(),
};
self.to_any()
}
Self::Producers(producers) => {
writer.producers(producers);
*self = Self::Any {
name: name.into(),
data: data.into(),
};
self.to_any()
}
Self::Daku(daku) => {
writer.daku(daku)?;
*self = Self::Any {
name: name.into(),
data: data.into(),
};
self.to_any()
}
Self::Any { name, data } => Some((&name[..], &data[..])),
}
}
pub fn to(&self) -> Option<Self> {
let Self::Any { name, data } = self else {
return None;
};
let Cow::Borrowed(data) = data else {
return None;
};
let mut reader = Reader::new(data);
Some(match &name[..] {
"name" => {
let names = reader.names()?;
reader.end()?;
Self::Name(names)
}
"producers" => {
let producers = reader.producers()?;
reader.end()?;
Self::Producers(producers)
}
"daku" => {
let daku = reader.daku()?;
reader.end()?;
Self::Daku(daku)
}
_ => return None,
})
}
}