Add Sequence impl, other changes/adjustments

This commit is contained in:
F. Levi 2024-09-17 23:10:59 +03:00
parent 6688604a93
commit b6c5a57932
3 changed files with 47 additions and 18 deletions

View File

@ -144,7 +144,7 @@ impl HeedAuthStore {
actions.insert(Action::MetricsGet); actions.insert(Action::MetricsGet);
} }
other => { other => {
actions.insert(*other); actions.insert(other);
} }
} }
} }

View File

@ -38,7 +38,7 @@ time = { version = "0.3.36", features = [
] } ] }
tokio = "1.38" tokio = "1.38"
uuid = { version = "1.10.0", features = ["serde", "v4"] } uuid = { version = "1.10.0", features = ["serde", "v4"] }
bitflags = {version = "2.6.0", features = ["serde"] } bitflags = {version = "2.6.0" }
[dev-dependencies] [dev-dependencies]
insta = "1.39.0" insta = "1.39.0"

View File

@ -222,7 +222,8 @@ bitflags! {
} }
impl Action { impl Action {
const SERIALIZATION_MAP: [(&'static str, Self); 34] = [ // @TODO: Consider using https://github.com/rust-phf/rust-phf
const SERDE_MAP_ARR: [(&'static str, Self); 34] = [
("*", Self::All), ("*", Self::All),
("search", Self::Search), ("search", Self::Search),
("documents.*", Self::DocumentsAll), ("documents.*", Self::DocumentsAll),
@ -311,7 +312,7 @@ impl<E: DeserializeError> Deserr<E> for Action {
) -> Result<Self, E> { ) -> Result<Self, E> {
match value { match value {
deserr::Value::String(s) => { deserr::Value::String(s) => {
match Self::SERIALIZATION_MAP.iter().find(|(serialized, _)| s == *serialized) { match Self::SERDE_MAP_ARR.iter().find(|(serialized, _)| s == *serialized) {
Some((_, action)) => Ok(*action), Some((_, action)) => Ok(*action),
None => Err(deserr::take_cf_content(E::error::<std::convert::Infallible>( None => Err(deserr::take_cf_content(E::error::<std::convert::Infallible>(
None, None,
@ -332,6 +333,20 @@ impl<E: DeserializeError> Deserr<E> for Action {
} }
} }
impl Serialize for Action {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Self::SERDE_MAP_ARR
.iter()
.find(|(_, action)| self == action)
.map(|(serialized, _)| serializer.serialize_str(serialized))
// should always be found, so unwrap is safe to use
.unwrap()
}
}
impl<'de> Deserialize<'de> for Action { impl<'de> Deserialize<'de> for Action {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -349,9 +364,8 @@ impl<'de> Deserialize<'de> for Action {
where where
E: serde::de::Error, E: serde::de::Error,
{ {
// @TODO: Make a to_serialized and to_desiralized on Action // @TODO: Make a to_serialized and to_desiralized on Action perhaps
match Self::Value::SERIALIZATION_MAP.iter().find(|(serialized, _)| s == *serialized) match Self::Value::SERDE_MAP_ARR.iter().find(|(serialized, _)| s == *serialized) {
{
Some((_, action)) => Ok(*action), Some((_, action)) => Ok(*action),
None => Err(E::invalid_value(serde::de::Unexpected::Str(s), &"a valid action")), None => Err(E::invalid_value(serde::de::Unexpected::Str(s), &"a valid action")),
} }
@ -362,17 +376,32 @@ impl<'de> Deserialize<'de> for Action {
} }
} }
impl Serialize for Action { impl Sequence for Action {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> const CARDINALITY: usize = Self::SERDE_MAP_ARR.len();
where
S: Serializer, fn next(&self) -> Option<Self> {
{ let next_index = self.bits() as usize + 1;
Self::SERIALIZATION_MAP if next_index == Self::CARDINALITY {
.iter() None
.find(|(_, action)| self == action) } else {
.map(|(serialized, _)| serializer.serialize_str(serialized)) Some(Self::SERDE_MAP_ARR[next_index].1)
// should always be found, so unwrap is safe to use }
.unwrap() }
fn previous(&self) -> Option<Self> {
if self.bits() == 0 {
None
} else {
Some(Self::SERDE_MAP_ARR[self.bits() as usize - 1].1)
}
}
fn first() -> Option<Self> {
Some(Self::SERDE_MAP_ARR[0].1)
}
fn last() -> Option<Self> {
Some(Self::SERDE_MAP_ARR[Self::CARDINALITY - 1].1)
} }
} }