use std::{
collections::HashMap,
fmt::{Display, Formatter},
str::FromStr,
};
use alpm_parsers::custom_ini::parser::Item;
use alpm_types::SchemaVersion;
use crate::Error;
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum Schema {
V1(SchemaVersion),
V2(SchemaVersion),
}
impl Schema {
pub fn inner(&self) -> &SchemaVersion {
match self {
Schema::V1(v) => v,
Schema::V2(v) => v,
}
}
pub fn from_contents(contents: &str) -> Result<Schema, Error> {
let raw_buildinfo: HashMap<String, Item> = alpm_parsers::custom_ini::from_str(contents)?;
if let Some(Item::Value(version)) = raw_buildinfo.get("format") {
Self::from_str(version)
} else {
Err(Error::MissingFormatField)
}
}
}
impl Default for Schema {
fn default() -> Self {
match SchemaVersion::from_str("1") {
Ok(v) => Schema::V1(v),
Err(e) => panic!("failed to create default schema: {e}"),
}
}
}
impl FromStr for Schema {
type Err = Error;
fn from_str(s: &str) -> Result<Schema, Self::Err> {
match SchemaVersion::from_str(s) {
Ok(version) => Self::try_from(version),
Err(_) => Err(Error::UnsupportedSchemaVersion(s.to_string())),
}
}
}
impl TryFrom<SchemaVersion> for Schema {
type Error = Error;
fn try_from(value: SchemaVersion) -> Result<Self, Self::Error> {
match value.inner().major {
1 => Ok(Schema::V1(value)),
2 => Ok(Schema::V2(value)),
_ => Err(Error::UnsupportedSchemaVersion(value.to_string())),
}
}
}
impl Display for Schema {
fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
write!(
fmt,
"{}",
match self {
Schema::V1(_) => "1",
Schema::V2(_) => "2",
}
)
}
}