From 263ddb654538d65e71c763f490399fc84ce1cd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Wed, 9 Oct 2024 16:20:46 +0200 Subject: [PATCH] identifiers: Improve API of Signatures Implement `Deref` and `DerefMut` to `BTreeMap`. Implement `From`, `Extend` and `FromIterator` from a list of `(entity, key_identifier, value)` tuples Rename `Signatures::insert` to `Signatures::insert_signature` to let `Signatures::insert` dereference to `BTreeMap::insert`. --- crates/ruma-common/CHANGELOG.md | 5 ++ .../ruma-common/src/identifiers/signatures.rs | 73 +++++++++++++++---- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/crates/ruma-common/CHANGELOG.md b/crates/ruma-common/CHANGELOG.md index 612b2ff2..a2916646 100644 --- a/crates/ruma-common/CHANGELOG.md +++ b/crates/ruma-common/CHANGELOG.md @@ -25,6 +25,8 @@ Breaking changes: - The `(owned_)server_signing_key_id` macros were removed. For compile-time validated construction, use `ServerSigningKeyId::from_parts` with a `SigningKeyAlgorithm` and the `server_signing_key_version` macro. +- Rename `Signatures::insert` to `Signatures::insert_signature`. + `Signatures::insert` is now dereferenced to `BTreeMap::insert`. Improvements: @@ -40,6 +42,9 @@ Improvements: - Implement `Eq` and `PartialEq` for `Metadata` - Allow constructing `api::error::MatrixErrorBody::NotJson` outside of this crate. +- Improve the API of `Signatures`, by implementing `Deref` and `DerefMut`, as + well as `From`, `Extend` and `FromIterator` from a list of + `(entity, key_identifier, value)` tuples. # 0.13.0 diff --git a/crates/ruma-common/src/identifiers/signatures.rs b/crates/ruma-common/src/identifiers/signatures.rs index 167836f0..81581e1a 100644 --- a/crates/ruma-common/src/identifiers/signatures.rs +++ b/crates/ruma-common/src/identifiers/signatures.rs @@ -1,4 +1,7 @@ -use std::{borrow::Borrow, collections::BTreeMap}; +use std::{ + collections::BTreeMap, + ops::{Deref, DerefMut}, +}; use serde::{Deserialize, Serialize}; @@ -10,7 +13,7 @@ use super::{ /// Map of key identifier to signature values. pub type EntitySignatures = BTreeMap, String>; -/// Map of all signatures, grouped by entity +/// Map of all signatures, grouped by entity. /// /// ``` /// # use ruma_common::{server_name, server_signing_key_version, ServerSigningKeyId, Signatures, SigningKeyAlgorithm}; @@ -22,22 +25,22 @@ pub type EntitySignatures = BTreeMap, String>; /// let server_name = server_name!("example.org"); /// let signature = /// "YbJva03ihSj5mPk+CHMJKUKlCXCPFXjXOK6VqBnN9nA2evksQcTGn6hwQfrgRHIDDXO2le49x7jnWJHMJrJoBQ"; -/// signatures.insert(server_name, key_identifier, signature.into()); +/// signatures.insert_signature(server_name, key_identifier, signature.into()); /// ``` -#[derive(Clone, Debug, Default, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] #[serde(transparent)] pub struct Signatures(BTreeMap>); impl Signatures { /// Creates an empty signature map. pub fn new() -> Self { - Self(BTreeMap::new()) + Self::default() } - /// Add a signature for the given server name and key identifier. + /// Add a signature for the given entity and key identifier. /// /// If there was already one, it is returned. - pub fn insert( + pub fn insert_signature( &mut self, entity: E, key_identifier: OwnedSigningKeyId, @@ -45,15 +48,6 @@ impl Signatures { ) -> Option { self.0.entry(entity).or_default().insert(key_identifier, value) } - - /// Returns a reference to the signatures corresponding to the entities. - pub fn get(&self, entity: &Q) -> Option<&EntitySignatures> - where - E: Borrow, - Q: Ord + ?Sized, - { - self.0.get(entity) - } } /// Map of server signatures for an event, grouped by server. @@ -61,3 +55,50 @@ pub type ServerSignatures = Signatures; + +impl Default for Signatures { + fn default() -> Self { + Self(Default::default()) + } +} + +impl Deref for Signatures { + type Target = BTreeMap>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Signatures { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From<[(E, OwnedSigningKeyId, String); N]> + for Signatures +{ + fn from(value: [(E, OwnedSigningKeyId, String); N]) -> Self { + value.into_iter().collect() + } +} + +impl FromIterator<(E, OwnedSigningKeyId, String)> + for Signatures +{ + fn from_iter, String)>>(iter: T) -> Self { + iter.into_iter().fold(Self::new(), |mut acc, (entity, key_identifier, value)| { + acc.insert_signature(entity, key_identifier, value); + acc + }) + } +} + +impl Extend<(E, OwnedSigningKeyId, String)> for Signatures { + fn extend, String)>>(&mut self, iter: T) { + for (entity, key_identifier, value) in iter { + self.insert_signature(entity, key_identifier, value); + } + } +}