97 lines
2.6 KiB
Rust
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)
|
|
}
|
|
}
|