use std::{
fmt::{Display, Formatter},
fs::File,
path::Path,
str::FromStr,
};
use alpm_common::FileFormatSchema;
use alpm_types::{SchemaVersion, semver_version::Version};
use fluent_i18n::t;
use winnow::Parser;
use crate::{Error, source_info::parser::SourceInfoContent};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SourceInfoSchema {
V1(SchemaVersion),
}
impl FileFormatSchema for SourceInfoSchema {
type Err = Error;
fn inner(&self) -> &SchemaVersion {
match self {
SourceInfoSchema::V1(v) => v,
}
}
fn derive_from_file(file: impl AsRef<Path>) -> Result<Self, Error>
where
Self: Sized,
{
let file = file.as_ref();
Self::derive_from_reader(File::open(file).map_err(|source| Error::IoPath {
path: file.to_path_buf(),
context: t!("error-io-deriving-schema-from-srcinfo-file"),
source,
})?)
}
fn derive_from_reader(reader: impl std::io::Read) -> Result<Self, Error>
where
Self: Sized,
{
let mut buf = String::new();
let mut reader = reader;
reader
.read_to_string(&mut buf)
.map_err(|source| Error::Io {
context: t!("error-io-deriving-schema-from-srcinfo-data"),
source,
})?;
Self::derive_from_str(&buf)
}
fn derive_from_str(s: &str) -> Result<SourceInfoSchema, Error> {
let _parsed = SourceInfoContent::parser
.parse(s.replace('\t', " ").as_str())
.map_err(|err| Error::ParseError(format!("{err}")))?;
Ok(SourceInfoSchema::V1(SchemaVersion::new(Version::new(
1, 0, 0,
))))
}
}
impl Default for SourceInfoSchema {
fn default() -> Self {
Self::V1(SchemaVersion::new(Version::new(1, 0, 0)))
}
}
impl FromStr for SourceInfoSchema {
type Err = Error;
fn from_str(s: &str) -> Result<SourceInfoSchema, Self::Err> {
match SchemaVersion::from_str(s) {
Ok(version) => Self::try_from(version),
Err(_) => Err(Error::UnsupportedSchemaVersion(s.to_string())),
}
}
}
impl TryFrom<SchemaVersion> for SourceInfoSchema {
type Error = Error;
fn try_from(value: SchemaVersion) -> Result<Self, Self::Error> {
match value.inner().major {
1 => Ok(SourceInfoSchema::V1(value)),
_ => Err(Error::UnsupportedSchemaVersion(value.to_string())),
}
}
}
impl Display for SourceInfoSchema {
fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
write!(
fmt,
"{}",
match self {
SourceInfoSchema::V1(version) => version.inner().major,
}
)
}
}