legacympt-rs/addonscript/src/manifest/installer.rs
2021-08-29 15:14:10 +02:00

97 lines
2.6 KiB
Rust

use serde::{de::Visitor, Deserializer};
use std::{path::PathBuf, str::FromStr};
use thiserror::Error;
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub enum Installer {
Override,
Dir(PathBuf),
}
#[derive(Debug, Error)]
pub enum InstallerParseError {
#[error("Unknown Installer type")]
UnknownType,
#[error("Invalid installer arguments")]
InvalidArguments,
#[error("Invalid installer syntax")]
InvalidSyntax,
}
impl FromStr for Installer {
type Err = InstallerParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut splits = s.split(':');
let installer_type = splits.next().ok_or(InstallerParseError::InvalidSyntax)?;
match installer_type {
"internal.override" => {
if splits.count() == 0 {
Ok(Installer::Override)
} else {
Err(InstallerParseError::InvalidArguments)
}
},
"internal.dir" => {
let dir = splits.next().ok_or(InstallerParseError::InvalidArguments)?;
let dir = PathBuf::from(dir);
if splits.count() == 0 {
Ok(Installer::Dir(dir))
} else {
Err(InstallerParseError::InvalidArguments)
}
},
_ => Err(InstallerParseError::UnknownType),
}
}
}
impl ToString for Installer {
fn to_string(&self) -> String {
match self {
Installer::Override => String::from("internal.override"),
Installer::Dir(dir) => format!("internal.dir:{}", dir.to_string_lossy()),
}
}
}
impl Serialize for Installer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl<'de> Deserialize<'de> for Installer {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct Vis;
impl<'de> Visitor<'de> for Vis {
type Value = Installer;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an AddonScript installer")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
v.parse::<Installer>()
.map_err(|e| E::custom(format!("invalid installer: {}", e)))
}
}
deserializer.deserialize_str(Vis)
}
}