From d6f9617207e472ab3249cfde5baa525e0ab10ebc Mon Sep 17 00:00:00 2001 From: "D. Scott Boggs" Date: Sun, 29 Jan 2023 08:59:40 -0500 Subject: [PATCH] Use macro to define ID types --- entities/src/account.rs | 39 +++------------------------- entities/src/attachment.rs | 37 +------------------------- entities/src/filter.rs | 39 ++-------------------------- entities/src/ids.rs | 50 ++++++++++++++++++++++++++++++++++++ entities/src/lib.rs | 25 ++++++++++-------- entities/src/list.rs | 31 ++-------------------- entities/src/mention.rs | 37 -------------------------- entities/src/notification.rs | 37 +------------------------- entities/src/push.rs | 38 ++------------------------- entities/src/relationship.rs | 39 ++-------------------------- entities/src/report.rs | 40 ++--------------------------- entities/src/status.rs | 38 --------------------------- examples/follow_profile.rs | 2 +- 13 files changed, 81 insertions(+), 371 deletions(-) create mode 100644 entities/src/ids.rs diff --git a/entities/src/account.rs b/entities/src/account.rs index 1c3940b..dbc6c72 100644 --- a/entities/src/account.rs +++ b/entities/src/account.rs @@ -4,9 +4,11 @@ use serde::{ de::{self, Deserializer, Unexpected}, Deserialize, Serialize, }; -use std::{fmt::Display, path::PathBuf}; +use std::path::PathBuf; use time::{serde::iso8601, OffsetDateTime}; +use crate::AccountId; + /// A struct representing an Account. #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] pub struct Account { @@ -54,41 +56,6 @@ pub struct Account { pub bot: Option, } -/// Wrapper type for a account ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct AccountId(String); - -impl AsRef for AccountId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl AccountId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for AccountId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - AccountId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); - /// A single name: value pair from a user's profile #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct MetadataField { diff --git a/entities/src/attachment.rs b/entities/src/attachment.rs index 772b160..489d0fa 100644 --- a/entities/src/attachment.rs +++ b/entities/src/attachment.rs @@ -1,7 +1,6 @@ //! Module containing everything related to media attachements. -use std::fmt::Display; - +use crate::AttachmentId; use serde::{Deserialize, Serialize}; /// A struct representing a media attachment. @@ -39,40 +38,6 @@ impl Attachment { self.url.is_some() } } -/// Wrapper type for a attachment ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct AttachmentId(String); - -impl AsRef for AttachmentId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl AttachmentId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for AttachmentId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - AttachmentId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); /// Information about the attachment itself. #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] diff --git a/entities/src/filter.rs b/entities/src/filter.rs index 5130562..b0fea28 100644 --- a/entities/src/filter.rs +++ b/entities/src/filter.rs @@ -1,8 +1,8 @@ -use std::fmt::Display; - use serde::{de::Visitor, Deserialize, Deserializer, Serialize}; use time::{serde::iso8601, OffsetDateTime}; +use crate::FilterId; + /// Represents a user-defined filter for determining which statuses should not /// be shown to the user. /// @@ -53,41 +53,6 @@ pub struct Filter { pub statuses: Vec, } -/// Wrapper type for a filter ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct FilterId(String); - -impl AsRef for FilterId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl FilterId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for FilterId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - FilterId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); - /// Represents the various types of Filter contexts #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] diff --git a/entities/src/ids.rs b/entities/src/ids.rs new file mode 100644 index 0000000..28dd28e --- /dev/null +++ b/entities/src/ids.rs @@ -0,0 +1,50 @@ +use serde::{Deserialize, Serialize}; +use std::fmt::Display; + +macro_rules! define_ids { + ($name:ident, $($rest:ident,)+) => { + define_ids!($name,); + static_assertions::assert_not_impl_any!( + $name: $(PartialEq<$rest>,)+ + ); + define_ids!($($rest,)+); + }; + ($name:ident,) => { + /// Wrapper type for a account ID string + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] + #[serde(transparent)] + pub struct $name(String); + + impl AsRef for $name { + fn as_ref(&self) -> &str { + &self.0 + } + } + + impl $name { + pub fn new(value: impl Into) -> Self { + Self(value.into()) + } + } + + impl Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } + } + }; + () => {} +} + +define_ids!( + AccountId, + AttachmentId, + FilterId, + ListId, + MentionId, + NotificationId, + SubscriptionId, + RelationshipId, + ReportId, + StatusId, +); diff --git a/entities/src/lib.rs b/entities/src/lib.rs index 7e200d6..fcdde3d 100644 --- a/entities/src/lib.rs +++ b/entities/src/lib.rs @@ -16,6 +16,9 @@ pub mod context; pub mod event; /// Data structures for ser/de of filter-related resources pub mod filter; +/// Type-safe ID values +pub mod ids; +pub use ids::*; /// Data structures for ser/de of instance-related resources pub mod instance; /// Data structures for ser/de of list-related resources @@ -46,21 +49,23 @@ pub struct Empty {} /// modules: pub mod prelude { pub use super::{ - account::{Account, AccountId, Source}, - attachment::{Attachment, AttachmentId, MediaType}, + account::{Account, Source}, + attachment::{Attachment, MediaType}, card::Card, context::Context, event::Event, - filter::{Filter, FilterContext, FilterId}, + filter::{Filter, FilterContext}, + ids::*, instance::*, - list::{List, ListId}, - mention::{Mention, MentionId}, - notification::{Notification, NotificationId}, - push::{Subscription, SubscriptionId}, - relationship::{Relationship, RelationshipId}, - report::{Report, ReportId}, + list::List, + mention::Mention, + notification::Notification, + push::Subscription, + relationship::Relationship, + report::Report, search_result::SearchResult, - status::{Application, Emoji, Status, StatusId}, + status::{Application, Emoji, Status}, + visibility::Visibility, Empty, }; } diff --git a/entities/src/list.rs b/entities/src/list.rs index 72a0aa2..7c1d506 100644 --- a/entities/src/list.rs +++ b/entities/src/list.rs @@ -1,37 +1,10 @@ use serde::{Deserialize, Serialize}; +use crate::ListId; + /// Used for ser/de of list resources #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] pub struct List { id: ListId, title: String, } - -/// Wrapper type for a list ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct ListId(String); - -impl AsRef for ListId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl ListId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -static_assertions::assert_not_impl_any!( - ListId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); diff --git a/entities/src/mention.rs b/entities/src/mention.rs index 2c00c2e..88b109a 100644 --- a/entities/src/mention.rs +++ b/entities/src/mention.rs @@ -1,5 +1,3 @@ -use std::fmt::Display; - use serde::{Deserialize, Serialize}; /// Represents a `mention` used in a status @@ -14,38 +12,3 @@ pub struct Mention { /// Account ID pub id: String, } - -/// Wrapper type for a mention ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct MentionId(String); - -impl AsRef for MentionId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl MentionId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for MentionId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - Mention: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); diff --git a/entities/src/notification.rs b/entities/src/notification.rs index a7fd729..adaa7f9 100644 --- a/entities/src/notification.rs +++ b/entities/src/notification.rs @@ -1,6 +1,6 @@ //! Module containing all info about notifications. -use std::fmt::Display; +use crate::NotificationId; use super::{account::Account, status::Status}; use serde::{Deserialize, Serialize}; @@ -24,41 +24,6 @@ pub struct Notification { pub status: Option, } -/// Wrapper type for a notification ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct NotificationId(String); - -impl AsRef for NotificationId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl NotificationId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for NotificationId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - NotificationId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); - /// The type of notification. #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] diff --git a/entities/src/push.rs b/entities/src/push.rs index af1d99e..b1ba3d6 100644 --- a/entities/src/push.rs +++ b/entities/src/push.rs @@ -1,7 +1,7 @@ -use std::fmt::Display; - use serde::{Deserialize, Serialize}; +use crate::SubscriptionId; + /// Represents the `alerts` key of the `Subscription` object #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] pub struct Alerts { @@ -28,40 +28,6 @@ pub struct Subscription { pub alerts: Option, } -/// Wrapper type for a subscription ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct SubscriptionId(String); - -impl AsRef for SubscriptionId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl SubscriptionId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for SubscriptionId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - SubscriptionId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); - pub mod add_subscription { use serde::Serialize; diff --git a/entities/src/relationship.rs b/entities/src/relationship.rs index 4ccd3ee..7b66481 100644 --- a/entities/src/relationship.rs +++ b/entities/src/relationship.rs @@ -1,10 +1,9 @@ //! module containing everything relating to a relationship with //! another account. - -use std::fmt::Display; - use serde::{Deserialize, Serialize}; +use crate::RelationshipId; + /// A struct containing information about a relationship with another account. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Relationship { @@ -33,37 +32,3 @@ pub struct Relationship { /// making calls to pleroma or mastodon<2.5.0 instances pub endorsed: Option, } - -/// Wrapper type for a relationship ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct RelationshipId(String); - -impl AsRef for RelationshipId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl RelationshipId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} -impl Display for RelationshipId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - RelationshipId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); diff --git a/entities/src/report.rs b/entities/src/report.rs index 4fa8c13..2fb1ea0 100644 --- a/entities/src/report.rs +++ b/entities/src/report.rs @@ -1,9 +1,8 @@ //! module containing information about a finished report of a user. - -use std::fmt::Display; - use serde::{Deserialize, Serialize}; +use crate::ReportId; + /// A struct containing info about a report. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Report { @@ -12,38 +11,3 @@ pub struct Report { /// The action taken in response to the report. pub action_taken: String, } - -/// Wrapper type for a report ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct ReportId(String); - -impl AsRef for ReportId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl ReportId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for ReportId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - ReportId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); diff --git a/entities/src/status.rs b/entities/src/status.rs index e270598..4195f79 100644 --- a/entities/src/status.rs +++ b/entities/src/status.rs @@ -1,9 +1,6 @@ //! Module containing all info relating to a status. -use std::fmt::Display; - use super::prelude::*; -use crate::{card::Card, visibility::Visibility}; use serde::{Deserialize, Serialize}; use time::{serde::iso8601, OffsetDateTime}; @@ -67,41 +64,6 @@ pub struct Status { pub pinned: Option, } -/// Wrapper type for a status ID string -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(transparent)] -pub struct StatusId(String); - -impl AsRef for StatusId { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl StatusId { - pub fn new(value: impl Into) -> Self { - Self(value.into()) - } -} - -impl Display for StatusId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -static_assertions::assert_not_impl_any!( - StatusId: PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, - PartialEq, -); - /// A mention of another user. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Mention { diff --git a/examples/follow_profile.rs b/examples/follow_profile.rs index 3965614..8ee28ac 100644 --- a/examples/follow_profile.rs +++ b/examples/follow_profile.rs @@ -5,7 +5,7 @@ use mastodon_async::Result; #[cfg(feature = "toml")] async fn run() -> Result<()> { - use mastodon_async::entities::account::AccountId; + use mastodon_async::entities::AccountId; let mastodon = register::get_mastodon_data().await?; let input = register::read_line("Enter the account id you'd like to follow: ")?; let account = AccountId::new(input.trim());