save Link as a different format in toml

This commit is contained in:
2026-03-20 13:08:56 +01:00
parent 03a127f24b
commit fcc65f68bb
3 changed files with 124 additions and 167 deletions

View File

@@ -1,15 +1,16 @@
use serde::{
Deserialize, Deserializer, Serialize, Serializer,
de::{self, Visitor},
};
use std::{
fmt::Debug,
fmt::{self, Debug},
path::{Path, PathBuf},
};
use serde::{Deserialize, Serialize};
use crate::types::mod_file::ModFile;
/// A link between a file from a mod and a destination in a ModdedInstance
#[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Hash)]
#[serde(from = "(PathBuf, PathBuf)", into = "(PathBuf,PathBuf)")]
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Link {
src: PathBuf,
dst: PathBuf,
@@ -36,18 +37,46 @@ impl Link {
}
}
impl From<(PathBuf, PathBuf)> for Link {
fn from(value: (PathBuf, PathBuf)) -> Self {
Self {
src: value.0,
dst: value.1,
impl Serialize for Link {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
if self.src == self.dst {
serializer.serialize_str(&self.src.to_string_lossy())
} else {
serializer.serialize_str(&format!(
"{} -> {}",
self.src.to_string_lossy(),
self.dst.to_string_lossy()
))
}
}
}
impl From<Link> for (PathBuf, PathBuf) {
fn from(value: Link) -> Self {
(value.src, value.dst)
impl<'de> Deserialize<'de> for Link {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct LinkVisitor;
impl<'de> Visitor<'de> for LinkVisitor {
type Value = Link;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(r#"a string like "src -> dst" or "path" if they are the same"#)
}
fn visit_str<E: de::Error>(self, value: &str) -> Result<Link, E> {
match value.split_once(" -> ") {
Some((src, dst)) => Ok(Link {
src: PathBuf::from(src),
dst: PathBuf::from(dst),
}),
None => Ok(Link {
src: PathBuf::from(value),
dst: PathBuf::from(value),
}),
}
}
}
deserializer.deserialize_str(LinkVisitor)
}
}