Add try_insert for SerdeAnyMap (#3012)
* add * use hashbrown method --------- Co-authored-by: toka <toka@tokas-MacBook-Air.local>
This commit is contained in:
parent
7bf7e4c2dc
commit
d3bae6a503
@ -29,18 +29,11 @@ pub trait HasMetadata {
|
|||||||
/// Add a metadata to the metadata map
|
/// Add a metadata to the metadata map
|
||||||
/// Returns error if the metadata is already there
|
/// Returns error if the metadata is already there
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_metadata_checked<M>(&mut self, meta: M) -> Result<(), Error>
|
fn try_add_metadata<M>(&mut self, meta: M) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
M: SerdeAny,
|
M: SerdeAny,
|
||||||
{
|
{
|
||||||
if self.has_metadata::<M>() {
|
self.metadata_map_mut().try_insert(meta)
|
||||||
return Err(Error::illegal_argument(format!(
|
|
||||||
"Tried to add a metadata of {}. But this will overwrite the existing metadata",
|
|
||||||
type_name::<M>()
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
self.metadata_map_mut().insert(meta);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets metadata, or inserts it using the given construction function `default`
|
/// Gets metadata, or inserts it using the given construction function `default`
|
||||||
@ -118,11 +111,7 @@ pub trait HasNamedMetadata {
|
|||||||
where
|
where
|
||||||
M: SerdeAny,
|
M: SerdeAny,
|
||||||
{
|
{
|
||||||
if self.has_named_metadata::<M>(name) {
|
self.named_metadata_map_mut().try_insert(name, meta)
|
||||||
return Err(Error::illegal_argument(format!("Tried to add a metadata of {} named {}. But this will overwrite the existing metadata", type_name::<M>(), name)));
|
|
||||||
}
|
|
||||||
self.named_metadata_map_mut().insert(name, meta);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a metadata to the metadata map
|
/// Add a metadata to the metadata map
|
||||||
|
@ -305,6 +305,8 @@ pub enum Error {
|
|||||||
EmptyOptional(String, ErrorBacktrace),
|
EmptyOptional(String, ErrorBacktrace),
|
||||||
/// Key not in Map
|
/// Key not in Map
|
||||||
KeyNotFound(String, ErrorBacktrace),
|
KeyNotFound(String, ErrorBacktrace),
|
||||||
|
/// Key already exists and should not overwrite
|
||||||
|
KeyExists(String, ErrorBacktrace),
|
||||||
/// No elements in the current item
|
/// No elements in the current item
|
||||||
Empty(String, ErrorBacktrace),
|
Empty(String, ErrorBacktrace),
|
||||||
/// End of iteration
|
/// End of iteration
|
||||||
@ -365,6 +367,15 @@ impl Error {
|
|||||||
Error::KeyNotFound(arg.into(), ErrorBacktrace::new())
|
Error::KeyNotFound(arg.into(), ErrorBacktrace::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Key already exists in Map
|
||||||
|
#[must_use]
|
||||||
|
pub fn key_exists<S>(arg: S) -> Self
|
||||||
|
where
|
||||||
|
S: Into<String>,
|
||||||
|
{
|
||||||
|
Error::KeyExists(arg.into(), ErrorBacktrace::new())
|
||||||
|
}
|
||||||
|
|
||||||
/// No elements in the current item
|
/// No elements in the current item
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn empty<S>(arg: S) -> Self
|
pub fn empty<S>(arg: S) -> Self
|
||||||
@ -508,6 +519,10 @@ impl Display for Error {
|
|||||||
write!(f, "Key: `{0}` - not found", &s)?;
|
write!(f, "Key: `{0}` - not found", &s)?;
|
||||||
display_error_backtrace(f, b)
|
display_error_backtrace(f, b)
|
||||||
}
|
}
|
||||||
|
Self::KeyExists(s, b) => {
|
||||||
|
write!(f, "Key: `{0}` - already exists", &s)?;
|
||||||
|
display_error_backtrace(f, b)
|
||||||
|
}
|
||||||
Self::Empty(s, b) => {
|
Self::Empty(s, b) => {
|
||||||
write!(f, "No items in {0}", &s)?;
|
write!(f, "No items in {0}", &s)?;
|
||||||
display_error_backtrace(f, b)
|
display_error_backtrace(f, b)
|
||||||
|
@ -321,6 +321,15 @@ pub mod serdeany_registry {
|
|||||||
self.insert_boxed(Box::new(t));
|
self.insert_boxed(Box::new(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert an element into the map if it doesn't exist, else return error.
|
||||||
|
#[inline]
|
||||||
|
pub fn try_insert<T>(&mut self, t: T) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
T: crate::serdeany::SerdeAny,
|
||||||
|
{
|
||||||
|
self.try_insert_boxed(Box::new(t))
|
||||||
|
}
|
||||||
|
|
||||||
/// Insert a boxed element into the map.
|
/// Insert a boxed element into the map.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn insert_boxed<T>(&mut self, value: Box<T>)
|
pub fn insert_boxed<T>(&mut self, value: Box<T>)
|
||||||
@ -331,6 +340,21 @@ pub mod serdeany_registry {
|
|||||||
.insert(type_repr_owned::<T>(), value);
|
.insert(type_repr_owned::<T>(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert a boxed element into the map if it doesn't exist, else return error.
|
||||||
|
#[inline]
|
||||||
|
pub fn try_insert_boxed<T>(&mut self, value: Box<T>) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
T: crate::serdeany::SerdeAny,
|
||||||
|
{
|
||||||
|
match self.map.try_insert(type_repr_owned::<T>(), value) {
|
||||||
|
Ok(_) => (), // then it's fine
|
||||||
|
Err(hashbrown::hash_map::OccupiedError { entry: _, value }) => {
|
||||||
|
return Err(Error::key_exists(format!("Tried to add a metadata of type {:?}. But this will overwrite the existing metadata value {:?}", core::any::type_name::<T>(), value)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get an entry to an element in this map.
|
/// Get an entry to an element in this map.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[expect(unused_qualifications)]
|
#[expect(unused_qualifications)]
|
||||||
@ -600,6 +624,23 @@ pub mod serdeany_registry {
|
|||||||
self.entry::<T>(name.into()).insert(Box::new(val));
|
self.entry::<T>(name.into()).insert(Box::new(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert an element into the map if it doesn't exist, else return error.
|
||||||
|
#[inline]
|
||||||
|
#[expect(unused_qualifications)]
|
||||||
|
pub fn try_insert<T>(&mut self, name: &str, val: T) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
T: crate::serdeany::SerdeAny,
|
||||||
|
{
|
||||||
|
let outer = self.outer_map_mut::<T>();
|
||||||
|
match outer.try_insert(name.into(), Box::new(val)) {
|
||||||
|
Ok(_) => (), // then it's fine
|
||||||
|
Err(hashbrown::hash_map::OccupiedError { entry, value }) => {
|
||||||
|
return Err(Error::key_exists(format!("Tried to add a metadata of type {:?} named {:?}. But this will overwrite the existing metadata value {:?}", core::any::type_name::<T>(), entry.key(), value)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a reference to the type map.
|
/// Get a reference to the type map.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[expect(unused_qualifications)]
|
#[expect(unused_qualifications)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user