Add mastodon_async_entities
This patch move the entities module to a helper-crate. With this, we give the user the opportunity to use only the entities types in their codebase, if need be. One scenario where this is required came up in https://github.com/dscottboggs/mastodon-async/issues/38 TL;DR is: A user needed to be able to pass types like `Status` from a backend part of an application to a frontend which was compiled to WASM. Because mastodon_async depends on tokio, which does not compile to WASM (at least not with the features required by mastodon_async). One option would have been to provide types in the application code which can be constructed from mastodon_asyncs entity types. This would lead to _a lot_ of code duplication (over several projects still,... but that's rather undesireable anyways). The solution mastodon_async offers with this patch is a helper-crate which only contains the entity types: mastodon_async_entities. mastodon_async publicly exports the whole mastodon_async_entities crate, so users do not have to depend on the latter directly. In addition to the `entities` module from mastodon_async, also the `Visibility` type had to be moved. `mastodon_async_entities` also got an own `Error` type, which `mastodon_async::Error` can of course wrap. Signed-off-by: Matthias Beyer <mail@beyermatthias.de> Suggested-by: D. Scott Boggs <scott@tams.tech>
This commit is contained in:
parent
02de9f5d32
commit
af3facfbf0
12
Cargo.toml
12
Cargo.toml
|
@ -1,3 +1,11 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
|
||||
members = [
|
||||
".",
|
||||
"entities",
|
||||
]
|
||||
|
||||
[package]
|
||||
name = "mastodon-async"
|
||||
version = "1.0.3"
|
||||
|
@ -13,6 +21,10 @@ repository = "https://github.com/dscottboggs/mastodon-async.git"
|
|||
[package.metadata.docs.rs]
|
||||
features = ["all"]
|
||||
|
||||
[dependencies.mastodon-async-entities]
|
||||
path = "./entities"
|
||||
version = "1.0.3"
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.25"
|
||||
doc-comment = "0.3"
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "mastodon-async-entities"
|
||||
version = "1.0.3"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.25"
|
||||
log = { version = "0.4", features = ["kv_unstable", "serde", "std", "kv_unstable_serde", "kv_unstable_std"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
thiserror = "1"
|
||||
time = { version = "0.3", features = ["parsing", "serde", "formatting"] }
|
|
@ -1,6 +1,5 @@
|
|||
//! A module containing everything relating to a account returned from the api.
|
||||
|
||||
use crate::status_builder;
|
||||
use serde::{
|
||||
de::{self, Deserializer, Unexpected},
|
||||
Deserialize, Serialize,
|
||||
|
@ -65,7 +64,7 @@ pub struct MetadataField {
|
|||
}
|
||||
|
||||
impl MetadataField {
|
||||
pub(crate) fn new(name: &str, value: &str) -> MetadataField {
|
||||
pub fn new(name: &str, value: &str) -> MetadataField {
|
||||
MetadataField {
|
||||
name: name.into(),
|
||||
value: value.into(),
|
||||
|
@ -76,7 +75,7 @@ impl MetadataField {
|
|||
/// An extra object given from `verify_credentials` giving defaults about a user
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
pub struct Source {
|
||||
privacy: Option<status_builder::Visibility>,
|
||||
privacy: Option<crate::visibility::Visibility>,
|
||||
#[serde(deserialize_with = "string_or_bool")]
|
||||
sensitive: bool,
|
||||
note: Option<String>,
|
||||
|
@ -109,33 +108,33 @@ fn string_or_bool<'de, D: Deserializer<'de>>(val: D) -> ::std::result::Result<bo
|
|||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, PartialEq, Eq)]
|
||||
pub(crate) struct UpdateSource {
|
||||
pub struct UpdateSource {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) privacy: Option<status_builder::Visibility>,
|
||||
pub privacy: Option<crate::visibility::Visibility>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) sensitive: Option<bool>,
|
||||
pub sensitive: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, PartialEq, Eq)]
|
||||
pub(crate) struct Credentials {
|
||||
pub struct Credentials {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) display_name: Option<String>,
|
||||
pub display_name: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) note: Option<String>,
|
||||
pub note: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) avatar: Option<PathBuf>,
|
||||
pub avatar: Option<PathBuf>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) header: Option<PathBuf>,
|
||||
pub header: Option<PathBuf>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) source: Option<UpdateSource>,
|
||||
pub source: Option<UpdateSource>,
|
||||
#[serde(serialize_with = "fields_attributes_ser::ser")]
|
||||
pub(crate) fields_attributes: Vec<MetadataField>,
|
||||
pub fields_attributes: Vec<MetadataField>,
|
||||
}
|
||||
|
||||
mod fields_attributes_ser {
|
||||
use super::*;
|
||||
use serde::ser::{SerializeMap, Serializer};
|
||||
pub(crate) fn ser<S>(attrs: &Vec<MetadataField>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
pub fn ser<S>(attrs: &Vec<MetadataField>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
|
@ -0,0 +1,6 @@
|
|||
/// Error type
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("unrecognized visibility '{invalid}'")]
|
||||
VisibilityParsingError { invalid: String },
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::entities::{notification::Notification, status::Status};
|
||||
use crate::{notification::Notification, status::Status};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
@ -0,0 +1,66 @@
|
|||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Error types for this crate
|
||||
pub mod error;
|
||||
|
||||
/// Data structures for ser/de of account-related resources
|
||||
pub mod account;
|
||||
/// Data structures for ser/de of attachment-related resources
|
||||
pub mod attachment;
|
||||
/// Data structures for ser/de of card-related resources
|
||||
pub mod card;
|
||||
/// Data structures for ser/de of contetx-related resources
|
||||
pub mod context;
|
||||
/// Data structures for ser/de of streaming events
|
||||
pub mod event;
|
||||
/// Data structures for ser/de of filter-related resources
|
||||
pub mod filter;
|
||||
/// Data structures for ser/de of instance-related resources
|
||||
pub mod instance;
|
||||
/// Data structures for ser/de of list-related resources
|
||||
pub mod list;
|
||||
/// Data structures for ser/de of mention-related resources
|
||||
pub mod mention;
|
||||
/// Data structures for ser/de of notification-related resources
|
||||
pub mod notification;
|
||||
/// Data structures for ser/de of push-subscription-related resources
|
||||
pub mod push;
|
||||
/// Data structures for ser/de of relationship-related resources
|
||||
pub mod relationship;
|
||||
/// Data structures for ser/de of report-related resources
|
||||
pub mod report;
|
||||
/// Data structures for ser/de of search-related resources
|
||||
pub mod search_result;
|
||||
/// Data structures for ser/de of status-related resources
|
||||
pub mod status;
|
||||
/// Data structure for ser/de visibility
|
||||
pub mod visibility;
|
||||
|
||||
/// An empty JSON object.
|
||||
#[derive(Deserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Empty {}
|
||||
|
||||
/// The purpose of this module is to alleviate imports of many common
|
||||
/// structs by adding a glob import to the top of mastodon heavy
|
||||
/// modules:
|
||||
pub mod prelude {
|
||||
pub use super::{
|
||||
account::{Account, Source},
|
||||
attachment::{Attachment, MediaType},
|
||||
card::Card,
|
||||
context::Context,
|
||||
event::Event,
|
||||
filter::{Filter, FilterContext},
|
||||
instance::*,
|
||||
list::List,
|
||||
mention::Mention,
|
||||
notification::Notification,
|
||||
push::Subscription,
|
||||
relationship::Relationship,
|
||||
report::Report,
|
||||
search_result::SearchResult,
|
||||
status::{Application, Emoji, Status},
|
||||
Empty,
|
||||
};
|
||||
}
|
|
@ -26,48 +26,48 @@ pub struct Subscription {
|
|||
pub alerts: Option<Alerts>,
|
||||
}
|
||||
|
||||
pub(crate) mod add_subscription {
|
||||
use serde::Serialize;
|
||||
|
||||
use super::Alerts;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Default)]
|
||||
pub(crate) struct Form {
|
||||
pub(crate) subscription: Subscription,
|
||||
pub(crate) data: Option<Data>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub(crate) struct Subscription {
|
||||
pub(crate) endpoint: String,
|
||||
pub(crate) keys: Keys,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub(crate) struct Keys {
|
||||
pub(crate) p256dh: String,
|
||||
pub(crate) auth: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub(crate) struct Data {
|
||||
pub(crate) alerts: Option<Alerts>,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod update_data {
|
||||
pub mod add_subscription {
|
||||
use serde::Serialize;
|
||||
|
||||
use super::Alerts;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub(crate) struct Data {
|
||||
pub(crate) alerts: Option<Alerts>,
|
||||
pub struct Form {
|
||||
pub subscription: Subscription,
|
||||
pub data: Option<Data>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub(crate) struct Form {
|
||||
pub(crate) id: String,
|
||||
pub(crate) data: Data,
|
||||
pub struct Subscription {
|
||||
pub endpoint: String,
|
||||
pub keys: Keys,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub struct Keys {
|
||||
pub p256dh: String,
|
||||
pub auth: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub struct Data {
|
||||
pub alerts: Option<Alerts>,
|
||||
}
|
||||
}
|
||||
|
||||
pub mod update_data {
|
||||
use serde::Serialize;
|
||||
|
||||
use super::Alerts;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub struct Data {
|
||||
pub alerts: Option<Alerts>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Default)]
|
||||
pub struct Form {
|
||||
pub id: String,
|
||||
pub data: Data,
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
//! Module containing all info relating to a status.
|
||||
|
||||
use super::prelude::*;
|
||||
use crate::{entities::card::Card, status_builder::Visibility};
|
||||
use crate::{card::Card, visibility::Visibility};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::{serde::iso8601, OffsetDateTime};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
/// The visibility of a status.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Visibility {
|
||||
/// A Direct message to a user
|
||||
Direct,
|
||||
/// Only available to followers
|
||||
Private,
|
||||
/// Not shown in public timelines
|
||||
Unlisted,
|
||||
/// Posted to public timelines
|
||||
Public,
|
||||
}
|
||||
|
||||
impl Default for Visibility {
|
||||
fn default() -> Self {
|
||||
Visibility::Public
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Visibility {
|
||||
type Err = crate::error::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
"direct" => Ok(Visibility::Direct),
|
||||
"private" => Ok(Visibility::Private),
|
||||
"unlisted" => Ok(Visibility::Unlisted),
|
||||
"public" => Ok(Visibility::Public),
|
||||
invalid => Err(crate::error::Error::VisibilityParsingError {
|
||||
invalid: invalid.to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,61 +1,3 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
/// Data structures for ser/de of account-related resources
|
||||
pub mod account;
|
||||
/// Data structures for ser/de of attachment-related resources
|
||||
pub mod attachment;
|
||||
/// Data structures for ser/de of card-related resources
|
||||
pub mod card;
|
||||
/// Data structures for ser/de of contetx-related resources
|
||||
pub mod context;
|
||||
/// Data structures for ser/de of streaming events
|
||||
pub mod event;
|
||||
/// Data structures for ser/de of filter-related resources
|
||||
pub mod filter;
|
||||
/// Data structures for ser/de of instance-related resources
|
||||
pub mod instance;
|
||||
pub(crate) mod itemsiter;
|
||||
/// Data structures for ser/de of list-related resources
|
||||
pub mod list;
|
||||
/// Data structures for ser/de of mention-related resources
|
||||
pub mod mention;
|
||||
/// Data structures for ser/de of notification-related resources
|
||||
pub mod notification;
|
||||
/// Data structures for ser/de of push-subscription-related resources
|
||||
pub mod push;
|
||||
/// Data structures for ser/de of relationship-related resources
|
||||
pub mod relationship;
|
||||
/// Data structures for ser/de of report-related resources
|
||||
pub mod report;
|
||||
/// Data structures for ser/de of search-related resources
|
||||
pub mod search_result;
|
||||
/// Data structures for ser/de of status-related resources
|
||||
pub mod status;
|
||||
|
||||
/// An empty JSON object.
|
||||
#[derive(Deserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Empty {}
|
||||
|
||||
/// The purpose of this module is to alleviate imports of many common
|
||||
/// structs by adding a glob import to the top of mastodon heavy
|
||||
/// modules:
|
||||
pub mod prelude {
|
||||
pub use super::{
|
||||
account::{Account, Source},
|
||||
attachment::{Attachment, MediaType},
|
||||
card::Card,
|
||||
context::Context,
|
||||
event::Event,
|
||||
filter::{Filter, FilterContext},
|
||||
instance::*,
|
||||
list::List,
|
||||
mention::Mention,
|
||||
notification::Notification,
|
||||
push::Subscription,
|
||||
relationship::Relationship,
|
||||
report::Report,
|
||||
search_result::SearchResult,
|
||||
status::{Application, Emoji, Status},
|
||||
Empty,
|
||||
};
|
||||
}
|
||||
pub use mastodon_async_entities::*;
|
||||
|
|
|
@ -99,6 +99,9 @@ pub enum Error {
|
|||
/// larger than the system's usize allows.
|
||||
#[error("integer didn't fit in the target size")]
|
||||
IntConversion(#[from] TryFromIntError),
|
||||
/// Error from mastodon-async-entities
|
||||
#[error(transparent)]
|
||||
Entities(#[from] mastodon_async_entities::error::Error),
|
||||
/// Other errors
|
||||
#[error("other error: {0:?}")]
|
||||
Other(String),
|
||||
|
|
|
@ -92,11 +92,12 @@ pub use errors::{ApiError, Error, Result};
|
|||
pub use isolang::Language;
|
||||
pub use mastodon::{Mastodon, MastodonUnauthenticated};
|
||||
// pub use mastodon_client::{MastodonClient, MastodonUnauthenticated};
|
||||
pub use mastodon_async_entities::visibility::Visibility;
|
||||
pub use registration::Registration;
|
||||
pub use requests::{
|
||||
AddFilterRequest, AddPushRequest, StatusesRequest, UpdateCredsRequest, UpdatePushRequest,
|
||||
};
|
||||
pub use status_builder::{NewStatus, StatusBuilder, Visibility};
|
||||
pub use status_builder::{NewStatus, StatusBuilder};
|
||||
|
||||
/// Registering your App
|
||||
pub mod apps;
|
||||
|
@ -126,7 +127,6 @@ mod macros;
|
|||
pub mod prelude {
|
||||
pub use crate::{
|
||||
scopes::Scopes,
|
||||
status_builder::Visibility,
|
||||
Data,
|
||||
Mastodon,
|
||||
// MastodonClient,
|
||||
|
@ -134,6 +134,7 @@ pub mod prelude {
|
|||
Registration,
|
||||
StatusBuilder,
|
||||
StatusesRequest,
|
||||
Visibility,
|
||||
};
|
||||
}
|
||||
/// The mastodon client
|
||||
|
|
|
@ -6,15 +6,15 @@ use std::{
|
|||
use crate::{
|
||||
entities::account::{Credentials, MetadataField, UpdateSource},
|
||||
errors::Result,
|
||||
status_builder,
|
||||
};
|
||||
use mastodon_async_entities::visibility::Visibility;
|
||||
|
||||
/// Builder to pass to the Mastodon::update_credentials method
|
||||
///
|
||||
/// // Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// use mastodon_async::{prelude::*, status_builder::Visibility, UpdateCredsRequest};
|
||||
/// use mastodon_async::{prelude::*, entities::visibility::Visibility, UpdateCredsRequest};
|
||||
///
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
|
@ -35,7 +35,7 @@ pub struct UpdateCredsRequest {
|
|||
field_attributes: Vec<MetadataField>,
|
||||
|
||||
// UpdateSource fields
|
||||
privacy: Option<status_builder::Visibility>,
|
||||
privacy: Option<Visibility>,
|
||||
sensitive: Option<bool>,
|
||||
}
|
||||
|
||||
|
@ -126,13 +126,13 @@ impl UpdateCredsRequest {
|
|||
/// // Example
|
||||
///
|
||||
/// ```
|
||||
/// use mastodon_async::{status_builder::Visibility, UpdateCredsRequest};
|
||||
/// use mastodon_async::{entities::visibility::Visibility, UpdateCredsRequest};
|
||||
///
|
||||
/// let mut builder = UpdateCredsRequest::new();
|
||||
///
|
||||
/// builder.privacy(Visibility::Public);
|
||||
/// ```
|
||||
pub fn privacy(&mut self, privacy: status_builder::Visibility) -> &mut Self {
|
||||
pub fn privacy(&mut self, privacy: Visibility) -> &mut Self {
|
||||
self.privacy = Some(privacy);
|
||||
self
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ impl UpdateCredsRequest {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::entities::account::{Credentials, MetadataField, UpdateSource};
|
||||
use status_builder::Visibility;
|
||||
use mastodon_async_entities::visibility::Visibility;
|
||||
|
||||
#[test]
|
||||
fn test_update_creds_request_new() {
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use isolang::Language;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::format_err;
|
||||
use mastodon_async_entities::visibility::Visibility;
|
||||
|
||||
/// A builder pattern struct for constructing a status.
|
||||
///
|
||||
|
@ -37,7 +35,7 @@ impl StatusBuilder {
|
|||
/// // Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use mastodon_async::{status_builder::Visibility, prelude::*};
|
||||
/// use mastodon_async::{entities::visibility::Visibility, prelude::*};
|
||||
///
|
||||
/// let data = Data::default();
|
||||
/// let client = Mastodon::from(data);
|
||||
|
@ -150,7 +148,7 @@ impl StatusBuilder {
|
|||
/// // Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use mastodon_async::{prelude::*, status_builder::Visibility};
|
||||
/// use mastodon_async::{prelude::*, entities::visibility::Visibility};
|
||||
/// let status = StatusBuilder::new()
|
||||
/// .status("awooooooo")
|
||||
/// .visibility(Visibility::Public)
|
||||
|
@ -242,40 +240,6 @@ pub struct NewStatus {
|
|||
content_type: Option<String>,
|
||||
}
|
||||
|
||||
/// The visibility of a status.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Visibility {
|
||||
/// A Direct message to a user
|
||||
Direct,
|
||||
/// Only available to followers
|
||||
Private,
|
||||
/// Not shown in public timelines
|
||||
Unlisted,
|
||||
/// Posted to public timelines
|
||||
Public,
|
||||
}
|
||||
|
||||
impl Default for Visibility {
|
||||
fn default() -> Self {
|
||||
Visibility::Public
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Visibility {
|
||||
type Err = crate::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
"direct" => Ok(Visibility::Direct),
|
||||
"private" => Ok(Visibility::Private),
|
||||
"unlisted" => Ok(Visibility::Unlisted),
|
||||
"public" => Ok(Visibility::Public),
|
||||
invalid => Err(format_err!("unrecognized visibility '{invalid}'")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in New Issue