libqaul_types/users.rs
1//! Network user and session management
2//!
3//! `libqaul` is an abstraction over a distributed network of users,
4//! meaning that it is impossible to tell the underlying device
5//! configuration. When connecting to other applications on the
6//! network, this is always done between *users*.
7
8use crate::diff::{ItemDiff, SetDiff};
9use ratman_identity::Identity;
10use serde::{Deserialize, Serialize};
11use std::collections::{BTreeMap, BTreeSet};
12
13/// A random authentication token
14pub type Token = String;
15
16/// Wrapper to encode `User` authentication state
17///
18/// This structure can be aquired by challenging an authentication
19/// endpoint, such as `User::login` to yield a token. If a session for
20/// this `Identity` already exists, it will be re-used.
21#[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
22pub struct UserAuth(pub Identity, pub Token);
23
24/// A complete user profile with ID and metadata
25///
26/// This abstraction is used in the Service API (see `api` module),
27/// but is important beyond the API functions, and as such is not part
28/// of the API `models` module.
29///
30/// The user profile itself makes no destinction between local, remote
31/// or self users (the latter being the currently active user in a
32/// session)
33#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
34pub struct UserProfile {
35 /// A user's network (node) ID
36 pub id: Identity,
37 /// A human readable display-name (like @foobar)
38 pub handle: Option<String>,
39 /// A human's preferred call-sign ("Friends call me foo")
40 pub display_name: Option<String>,
41 /// A key-value list of things the user deems interesting about
42 /// themselves. This could be stuff like "gender", "preferred
43 /// languages" or whatever.
44 pub bio: BTreeMap<String, String>,
45 /// The set of services this user runs (should never be empty!)
46 pub services: BTreeSet<String>,
47 /// A users profile picture (some people like selfies)
48 pub avatar: Option<Vec<u8>>,
49}
50
51impl UserProfile {
52 /// Create a new user profile for a user ID
53 pub fn new(id: Identity) -> Self {
54 Self {
55 id,
56 handle: None,
57 display_name: None,
58 bio: BTreeMap::new(),
59 services: BTreeSet::new(),
60 avatar: None,
61 }
62 }
63
64 // /// Apply the given UserUpdate to this UserUpdate in-place
65 // pub fn apply(self, update: UserUpdate) -> Self {
66 // let mut new = self;
67 // update.apply_to(&mut new);
68 // new
69 // }
70
71 /// Do a contains-query on names to facilitate searching
72 ///
73 /// This means that the query string needs to be contained in it's
74 /// entirety in the display or real name strings to return a
75 /// match.
76 pub fn contains_query(&self, query: &str) -> bool {
77 (match &self.display_name {
78 None => false,
79 Some(v) => v.contains(query),
80 }) || (match &self.display_name {
81 None => false,
82 Some(v) => v.contains(query),
83 })
84 }
85
86 /// Do a fully fuzzy query on names to facilitate searching
87 pub fn fuzzy_query(&self, _query: &str) -> bool {
88 unimplemented!()
89 }
90
91 #[doc(hidden)]
92 pub fn generate_updates(&self, new: Self) -> UserUpdate {
93 let mut update = UserUpdate::default();
94
95 match (&self.handle, new.handle) {
96 (None, Some(name)) => update.handle = ItemDiff::Set(name),
97 (Some(_), None) => update.handle = ItemDiff::Unset,
98 (_, _) => {} // Ignore is the default
99 }
100
101 match (&self.display_name, new.display_name) {
102 (None, Some(name)) => update.display_name = ItemDiff::Set(name),
103 (Some(_), None) => update.display_name = ItemDiff::Unset,
104 (_, _) => {} // Ignore is the default
105 }
106
107 // TODO: implement other user updates
108
109 update
110 }
111}
112
113/// All the ways a UserData can change, as individual events.
114#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Debug, Clone)]
115#[serde(default)]
116pub struct UserUpdate {
117 /// Set or blank the User's handle
118 pub handle: ItemDiff<String>,
119 /// Set or blank the User's display name
120 pub display_name: ItemDiff<String>,
121 /// Add or update a biography line with the given key to the given value.
122 pub add_to_bio: Vec<(String, String)>,
123 /// Remove a biography line with the given key, or do nothing if it does not exist.
124 pub rm_from_bio: BTreeSet<String>,
125 /// Add a service with the given name.
126 pub services: BTreeSet<SetDiff<String>>,
127 /// Set or blank the User's avatar.
128 pub avi_data: ItemDiff<Vec<u8>>,
129}