summaryrefslogtreecommitdiffstats
path: root/src/session.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-03-19 22:41:55 -0500
committerToby Vincent <tobyv13@gmail.com>2023-03-19 22:41:55 -0500
commitd17bdb1e841f9d39bd7c3142afc71ccb86bcc69d (patch)
treecde260e43d013b354039ef3a757b4802a272093f /src/session.rs
parent465590929dad316bc07602fddaa09a6e36dcb66f (diff)
refactor: move session traits and stucts into module
Diffstat (limited to 'src/session.rs')
-rw-r--r--src/session.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/session.rs b/src/session.rs
new file mode 100644
index 0000000..ea3cc75
--- /dev/null
+++ b/src/session.rs
@@ -0,0 +1,92 @@
+use std::{
+ collections::{hash_map::Entry, HashMap},
+ fmt::Display,
+ iter::IntoIterator,
+ time::{Duration, SystemTime, UNIX_EPOCH},
+};
+
+use serde::{Deserialize, Serialize};
+
+pub trait SessionSource {
+ type Error;
+
+ type Iter: IntoIterator<Item = Session>;
+
+ fn sessions(&self) -> Result<Self::Iter, Self::Error>;
+
+ fn update(
+ &self,
+ mut hash_map: HashMap<String, Session>,
+ ) -> Result<HashMap<String, Session>, Self::Error> {
+ for session in self.sessions()? {
+ match hash_map.entry(session.name.to_owned()) {
+ Entry::Occupied(mut o) if &session > o.get() => {
+ o.insert(session);
+ }
+ Entry::Vacant(v) => {
+ v.insert(session);
+ }
+ _ => {}
+ }
+ }
+ Ok(hash_map)
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
+pub enum State {
+ Discovered,
+ Connected,
+ Updated,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
+pub struct Session {
+ pub state: State,
+
+ #[serde(with = "epoch_timestamp")]
+ pub timestamp: Duration,
+
+ pub name: String,
+}
+
+mod epoch_timestamp {
+ use std::time::Duration;
+
+ use serde::{self, Deserialize, Deserializer, Serializer};
+
+ pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_u64(duration.as_secs())
+ }
+
+ pub fn deserialize<'de, D>(d: D) -> Result<Duration, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ u64::deserialize(d).map(Duration::from_secs)
+ }
+}
+
+impl Display for Session {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.name)
+ }
+}
+
+impl From<String> for Session {
+ fn from(name: String) -> Self {
+ let timestamp = SystemTime::now()
+ .duration_since(UNIX_EPOCH)
+ .expect("Current time is pre-epoch. (Time traveler?)");
+
+ Self {
+ state: State::Discovered,
+ timestamp,
+ name,
+ }
+ }
+}
+