ncspot_types/
lib.rs

1#![crate_name = "ncspot_types"]
2
3//! This crate provides a set of types that derive `serde::Deserialize` that match the JSON
4//! output from [ncspot](https://github.com/hrkfdn/ncspot).
5//!
6//! Interior types are matched as closely as possible to the way the data is modelled inside
7//! of ncspot, with one exception: `duration` is deserialized as a `std::time::Duration` whereas
8//! internally, ncspot represents this as a `u32`.
9//!
10//! I'm not entirely convinced this is necessary yet, but it may be convenient when using the library.
11
12use chrono::offset::Utc;
13use chrono::DateTime;
14use serde::Deserialize;
15use std::time::Duration;
16
17/// A single event from ncspot
18#[derive(Debug, Deserialize, Clone)]
19pub struct Event {
20    pub mode: Mode,
21    pub playable: Playable,
22}
23
24/// Type of event, [Track] or [Episode]
25#[derive(Debug, Deserialize, Clone)]
26#[serde(untagged)]
27pub enum Playable {
28    Track(Track),
29    Episode(Episode),
30}
31
32/// Current playback mode
33#[derive(Debug, Deserialize, Clone, Copy)]
34pub enum Mode {
35    /// A [Track] or [Episode] is currently playing
36    Playing {
37        secs_since_epoch: usize,
38        nanos_since_epoch: usize,
39    },
40
41    /// A [Track] or [Episode] is currently paused
42    Paused { secs: usize, nanos: usize },
43
44    /// Emitted briefly when playing a chosen song
45    /// before then emitting a `Playing` event
46    Stopped,
47}
48
49/// A music track
50#[serde_with::serde_as]
51#[derive(Debug, Deserialize, Clone)]
52pub struct Track {
53    pub id: Option<String>,
54    pub uri: String,
55    pub title: String,
56    pub track_number: u32,
57    pub disc_number: i32,
58    #[serde_as(as = "serde_with::DurationMilliSeconds<u64>")]
59    pub duration: Duration,
60    pub artists: Vec<String>,
61    pub artist_ids: Vec<String>,
62    pub album: Option<String>,
63    pub album_id: Option<String>,
64    pub album_artists: Vec<String>,
65    pub cover_url: Option<String>,
66    pub url: String,
67    pub added_at: Option<DateTime<Utc>>,
68    pub list_index: usize,
69}
70
71/// A podcast episode
72#[serde_with::serde_as]
73#[derive(Debug, Deserialize, Clone)]
74pub struct Episode {
75    pub id: String,
76    pub uri: String,
77    pub duration: Duration,
78    pub name: String,
79    pub description: String,
80    pub release_date: DateTime<Utc>,
81    pub cover_url: Option<String>,
82    pub added_at: Option<DateTime<Utc>>,
83    pub list_index: usize,
84}