use std::collections::HashMap; use serde::{Deserialize, Deserializer, Serialize}; use sprout_core::PresenceStatus; #[derive(Serialize)] pub struct IdentityInfo { pub pubkey: String, pub display_name: String, } #[derive(Serialize, Deserialize)] pub struct ProfileInfo { pub pubkey: String, pub display_name: Option, pub avatar_url: Option, pub about: Option, pub nip05_handle: Option, } #[derive(Serialize, Deserialize)] pub struct UserProfileSummaryInfo { pub display_name: Option, pub avatar_url: Option, pub nip05_handle: Option, } #[derive(Serialize, Deserialize)] pub struct UsersBatchResponse { pub profiles: HashMap, pub missing: Vec, } #[derive(Serialize, Deserialize)] pub struct UserSearchResultInfo { pub pubkey: String, pub display_name: Option, pub avatar_url: Option, pub nip05_handle: Option, } #[derive(Serialize, Deserialize)] pub struct SearchUsersResponse { pub users: Vec, } #[derive(Serialize, Deserialize)] pub struct SetPresenceResponse { pub status: PresenceStatus, pub ttl_seconds: u64, } #[derive(Serialize, Deserialize)] pub struct ChannelInfo { pub id: String, pub name: String, pub channel_type: String, pub visibility: String, #[serde(deserialize_with = "deserialize_null_string_as_empty")] pub description: String, pub topic: Option, pub purpose: Option, pub member_count: i64, pub last_message_at: Option, pub archived_at: Option, pub participants: Vec, pub participant_pubkeys: Vec, #[serde(default = "default_true")] pub is_member: bool, } #[derive(Serialize, Deserialize)] pub struct ChannelDetailInfo { pub id: String, pub name: String, pub channel_type: String, pub visibility: String, #[serde(deserialize_with = "deserialize_null_string_as_empty")] pub description: String, pub topic: Option, pub topic_set_by: Option, pub topic_set_at: Option, pub purpose: Option, pub purpose_set_by: Option, pub purpose_set_at: Option, pub created_by: String, pub created_at: String, pub updated_at: String, pub archived_at: Option, pub member_count: i64, pub topic_required: bool, pub max_members: Option, pub nip29_group_id: Option, } #[derive(Serialize, Deserialize)] pub struct ChannelMemberInfo { pub pubkey: String, pub role: String, pub joined_at: String, pub display_name: Option, } #[derive(Serialize, Deserialize)] pub struct ChannelMembersResponse { pub members: Vec, pub next_cursor: Option, } #[derive(Serialize, Deserialize)] pub struct AddMembersResponse { pub added: Vec, pub errors: Vec, } #[derive(Serialize)] pub struct CreateChannelBody<'a> { pub name: &'a str, pub channel_type: &'a str, pub visibility: &'a str, pub description: Option<&'a str>, } #[derive(Serialize)] pub struct UpdateChannelBody<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub name: Option<&'a str>, #[serde(skip_serializing_if = "Option::is_none")] pub description: Option<&'a str>, } #[derive(Serialize)] pub struct SetTopicBody<'a> { pub topic: &'a str, } #[derive(Serialize)] pub struct SetPurposeBody<'a> { pub purpose: &'a str, } #[derive(Serialize)] pub struct AddMembersBody<'a> { pub pubkeys: &'a [String], #[serde(skip_serializing_if = "Option::is_none")] pub role: Option<&'a str>, } #[derive(Serialize)] pub struct UpdateProfileBody<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub display_name: Option<&'a str>, #[serde(skip_serializing_if = "Option::is_none")] pub avatar_url: Option<&'a str>, #[serde(skip_serializing_if = "Option::is_none")] pub about: Option<&'a str>, #[serde(skip_serializing_if = "Option::is_none")] pub nip05_handle: Option<&'a str>, } #[derive(Serialize)] pub struct SetPresenceBody { pub status: PresenceStatus, } #[derive(Serialize)] pub struct GetFeedQuery<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub since: Option, #[serde(skip_serializing_if = "Option::is_none")] pub limit: Option, #[serde(skip_serializing_if = "Option::is_none")] pub types: Option<&'a str>, } #[derive(Serialize)] pub struct SearchQueryParams<'a> { pub q: &'a str, #[serde(skip_serializing_if = "Option::is_none")] pub limit: Option, } #[derive(Serialize)] pub struct SendChannelMessageBody<'a> { pub content: &'a str, #[serde(skip_serializing_if = "Option::is_none")] pub parent_event_id: Option<&'a str>, pub broadcast_to_channel: bool, #[serde(skip_serializing_if = "Option::is_none")] pub media_tags: Option>>, #[serde(skip_serializing_if = "Vec::is_empty")] pub mention_pubkeys: Vec<&'a str>, } #[derive(Serialize)] pub struct AddReactionBody<'a> { pub emoji: &'a str, } #[derive(Serialize)] pub struct MintTokenBody<'a> { pub name: &'a str, pub scopes: &'a [String], #[serde(skip_serializing_if = "Option::is_none")] pub channel_ids: Option<&'a [String]>, #[serde(skip_serializing_if = "Option::is_none")] pub expires_in_days: Option, } #[derive(Serialize, Deserialize)] pub struct MintTokenResponse { pub id: String, pub token: String, pub name: String, pub scopes: Vec, pub channel_ids: Vec, pub created_at: String, pub expires_at: Option, } #[derive(Serialize, Deserialize)] pub struct TokenInfo { pub id: String, pub name: String, pub scopes: Vec, pub channel_ids: Vec, pub created_at: String, pub expires_at: Option, pub last_used_at: Option, pub revoked_at: Option, } #[derive(Serialize, Deserialize)] pub struct ListTokensResponse { pub tokens: Vec, } #[derive(Serialize, Deserialize)] pub struct RevokeAllTokensResponse { pub revoked_count: u64, } #[derive(Serialize, Deserialize)] pub struct FeedItemInfo { pub id: String, pub kind: u32, pub pubkey: String, pub content: String, pub created_at: u64, pub channel_id: Option, pub channel_name: String, pub tags: Vec>, pub category: String, } #[derive(Serialize, Deserialize)] pub struct FeedSections { pub mentions: Vec, pub needs_action: Vec, pub activity: Vec, pub agent_activity: Vec, } #[derive(Serialize, Deserialize)] pub struct FeedMeta { pub since: i64, pub total: u64, pub generated_at: i64, } #[derive(Serialize, Deserialize)] pub struct FeedResponse { pub feed: FeedSections, pub meta: FeedMeta, } #[derive(Serialize, Deserialize)] pub struct SearchHitInfo { pub event_id: String, pub content: String, pub kind: u32, pub pubkey: String, pub channel_id: String, pub channel_name: String, pub created_at: u64, pub score: f64, } #[derive(Serialize, Deserialize)] pub struct SearchResponse { pub hits: Vec, pub found: u64, } #[derive(Serialize, Deserialize)] pub struct SendChannelMessageResponse { pub event_id: String, pub parent_event_id: Option, pub root_event_id: Option, pub depth: u32, pub created_at: i64, } #[derive(Serialize)] pub struct GetUsersBatchBody<'a> { pub pubkeys: &'a [String], } fn deserialize_null_string_as_empty<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { Ok(Option::::deserialize(deserializer)?.unwrap_or_default()) } fn default_true() -> bool { true }