Skip to content

Commit

Permalink
Merge branch 'dev' into mfa
Browse files Browse the repository at this point in the history
  • Loading branch information
kozabrada123 committed Oct 13, 2024
2 parents 49a0742 + 0938dd8 commit b3a065b
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ jobs:
with:
cache-all-crates: "true"
prefix-key: "macos"
- uses: taiki-e/install-action@nextest
- name: Run WASM tests with Safari, Firefox, Chrome
run: |
rustup target add wasm32-unknown-unknown
Expand Down Expand Up @@ -126,6 +127,7 @@ jobs:
with:
cache-all-crates: "true"
prefix-key: "macos"
- uses: taiki-e/install-action@nextest
- name: Run WASM tests with Safari, Firefox, Chrome
run: |
rustup target add wasm32-unknown-unknown
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "chorus"
description = "A library for interacting with multiple Spacebar-compatible Instances at once."
version = "0.16.0"
version = "0.17.0"
license = "MPL-2.0"
edition = "2021"
repository = "https://github.com/polyphony-chat/chorus"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ To get started with Chorus, import it into your project by adding the following

```toml
[dependencies]
chorus = "0.16.0"
chorus = "0.17.0"
```

### Establishing a Connection
Expand Down
59 changes: 57 additions & 2 deletions src/types/entities/relationship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@ use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};

use crate::errors::ChorusError;
use crate::types::{Shared, Snowflake};

use super::{arc_rwlock_ptr_eq, PublicUser};

#[derive(Debug, Deserialize, Serialize, Clone, Default)]
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
/// See <https://discord-userdoccers.vercel.app/resources/user#relationship-structure>
pub struct Relationship {
/// The ID of the target user
#[cfg_attr(feature = "sqlx", sqlx(rename = "to_id"))]
pub id: Snowflake,
#[serde(rename = "type")]
#[cfg_attr(feature = "sqlx", sqlx(rename = "type"))]
pub relationship_type: RelationshipType,
/// The nickname of the user in this relationship
pub nickname: Option<String>,
#[cfg_attr(feature = "sqlx", sqlx(skip))] // Can be derived from the user id
/// The target user
pub user: Shared<PublicUser>,
/// When the user requested a relationship
pub since: Option<DateTime<Utc>>,
}

Expand Down Expand Up @@ -45,8 +54,7 @@ impl PartialEq for Relationship {
Copy,
Hash,
)]
#[cfg_attr(not(feature = "sqlx"), repr(u8))]
#[cfg_attr(feature = "sqlx", repr(i16))]
#[repr(u8)]
/// See <https://discord-userdoccers.vercel.app/resources/user#relationship-type>
pub enum RelationshipType {
Suggestion = 6,
Expand All @@ -58,3 +66,50 @@ pub enum RelationshipType {
Friends = 1,
None = 0,
}

#[cfg(feature = "sqlx")]
impl sqlx::Type<sqlx::Postgres> for RelationshipType {
fn type_info() -> <sqlx::Postgres as sqlx::Database>::TypeInfo {
<sqlx_pg_uint::PgU8 as sqlx::Type<sqlx::Postgres>>::type_info()
}
}

#[cfg(feature = "sqlx")]
impl<'q> sqlx::Encode<'q, sqlx::Postgres> for RelationshipType {
fn encode_by_ref(
&self,
buf: &mut <sqlx::Postgres as sqlx::Database>::ArgumentBuffer<'q>,
) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::from(*self as u8);
sqlx_pg_uint.encode_by_ref(buf)
}
}

#[cfg(feature = "sqlx")]
impl<'r> sqlx::Decode<'r, sqlx::Postgres> for RelationshipType {
fn decode(
value: <sqlx::Postgres as sqlx::Database>::ValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::decode(value)?;
Self::try_from(sqlx_pg_uint.to_uint()).map_err(|e| e.into())
}
}

impl TryFrom<u8> for RelationshipType {
type Error = ChorusError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
6 => Ok(Self::Suggestion),
5 => Ok(Self::Implicit),
4 => Ok(Self::Outgoing),
3 => Ok(Self::Incoming),
2 => Ok(Self::Blocked),
1 => Ok(Self::Friends),
0 => Ok(Self::None),
_ => Err(ChorusError::InvalidArguments {
error: format!("Value {} is not a valid RelationshipType", value),
}),
}
}
}
48 changes: 45 additions & 3 deletions src/types/entities/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,7 @@ bitflags::bitflags! {
PartialOrd,
Ord,
)]
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
#[cfg_attr(not(feature = "sqlx"), repr(u8))]
#[cfg_attr(feature = "sqlx", repr(i16))]
#[repr(u8)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
/// **User** premium (Nitro) type
///
Expand All @@ -252,6 +250,50 @@ pub enum PremiumType {
Tier3 = 3,
}

impl TryFrom<u8> for PremiumType {
type Error = ChorusError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::None),
1 => Ok(Self::Tier1),
2 => Ok(Self::Tier2),
3 => Ok(Self::Tier3),
_ => Err(ChorusError::InvalidArguments {
error: "Value is not a valid PremiumType".to_string(),
}),
}
}
}

#[cfg(feature = "sqlx")]
impl sqlx::Type<sqlx::Postgres> for PremiumType {
fn type_info() -> <sqlx::Postgres as sqlx::Database>::TypeInfo {
<sqlx_pg_uint::PgU8 as sqlx::Type<sqlx::Postgres>>::type_info()
}
}

#[cfg(feature = "sqlx")]
impl<'q> sqlx::Encode<'q, sqlx::Postgres> for PremiumType {
fn encode_by_ref(
&self,
buf: &mut <sqlx::Postgres as sqlx::Database>::ArgumentBuffer<'q>,
) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::from(*self as u8);
sqlx_pg_uint.encode_by_ref(buf)
}
}

#[cfg(feature = "sqlx")]
impl<'r> sqlx::Decode<'r, sqlx::Postgres> for PremiumType {
fn decode(
value: <sqlx::Postgres as sqlx::Database>::ValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
let sqlx_pg_uint = sqlx_pg_uint::PgU8::decode(value)?;
PremiumType::try_from(sqlx_pg_uint.to_uint()).map_err(|e| e.into())
}
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
/// # Reference
/// See <https://docs.discord.sex/resources/user#profile-metadata-object>
Expand Down
2 changes: 2 additions & 0 deletions src/types/events/ready.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub struct GatewayReady {
pub guilds: Vec<Guild>,
/// The presences of the user's non-offline friends and implicit relationships (depending on the `NO_AFFINE_USER_IDS` Gateway capability).
pub presences: Option<Vec<PresenceUpdate>>,
/// Undocumented. Seems to be a list of sessions the user is currently connected with.
/// On Discord.com, this includes the current session.
pub sessions: Option<Vec<Session>>,
/// Unique session ID, used for resuming connections
pub session_id: String,
Expand Down

0 comments on commit b3a065b

Please sign in to comment.