use core::{
ops::{Deref, DerefMut},
str::FromStr,
};
use alloc::{string::String, vec::Vec};
use crate::{ConstString, RemappingTarget};
use super::error::{Error, Result};
type RemappingEntry = (ConstString, RemappingTarget);
#[derive(Clone, Default)]
#[repr(transparent)]
pub struct RemappingList(Vec<RemappingEntry>);
impl core::fmt::Debug for RemappingList {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Remappings {{ ")?;
write!(f, "{:?}", &self.0)?;
write!(f, " }}")
}
}
impl Deref for RemappingList {
type Target = Vec<RemappingEntry>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for RemappingList {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl RemappingList {
pub fn add(&mut self, key: impl Into<ConstString>, target: impl Into<ConstString>) -> Result<()> {
let key = key.into();
let target = target.into();
let remap_to = if target.as_ref() == "{=}" {
(String::from("{") + &key + "}").into()
} else {
target
};
for (original, _remapped) in &self.0 {
if original == &key {
return Err(Error::AlreadyRemapped {
key,
remapped: "todo!()".into(),
});
}
}
let target = RemappingTarget::from_str(&remap_to)?;
self.0.push((key, target));
Ok(())
}
pub fn overwrite(&mut self, key: impl Into<ConstString>, target: impl Into<ConstString>) -> Result<()> {
let key = key.into();
let target = target.into();
let remap_to = if target.as_ref() == "{=}" {
(String::from("{") + &key + "}").into()
} else {
target
};
let target = RemappingTarget::from_str(&remap_to)?;
for (original, old_value) in &mut self.0 {
if original == &key {
*old_value = target;
return Ok(());
}
}
self.0.push((key, target));
Ok(())
}
#[must_use]
pub fn find(&self, key: &str) -> RemappingTarget {
for (original, remapped) in &self.0 {
if original.as_ref() == key {
return remapped.clone();
}
}
RemappingTarget::None(key.into())
}
pub fn shrink(&mut self) {
self.0.shrink_to_fit();
}
}
#[cfg(test)]
mod tests {
use super::*;
const fn is_normal<T: Sized + Send + Sync>() {}
#[test]
const fn normal_types() {
is_normal::<RemappingList>();
is_normal::<RemappingEntry>();
}
}