danceinterpreter_rs/traktor_api/
model.rs1use bytes::Bytes;
2use iced::futures::channel::mpsc;
3use serde::{Deserialize, Deserializer, Serialize};
4use std::net::SocketAddr;
5
6#[derive(Debug, Clone)]
7pub enum AppMessage {
8 Reconnect { debug_logging: bool },
9}
10
11#[derive(Debug, Clone)]
12pub enum ServerMessage {
13 Ready(mpsc::UnboundedSender<AppMessage>),
14 Connect {
15 time_offset_ms: i64,
16 initial_state: Box<State>,
17 },
18 Update(StateUpdate),
19 CoverImage {
20 path: String,
21 data: Bytes,
22 },
23 ClientChanged(Option<SocketAddr>),
24 Log(String),
25}
26
27#[derive(Debug, Copy, Clone)]
28pub enum ID {
29 A = 0,
30 B,
31 C,
32 D,
33}
34
35#[derive(Debug, Clone)]
36pub enum StateUpdate {
37 Mixer(MixerState),
38 Channel(ID, ChannelState),
39 DeckContent(ID, Box<DeckContentState>),
40 DeckPlayState(ID, DeckPlayState),
41}
42
43#[derive(Debug, Clone)]
44pub struct State {
45 pub mixer: MixerState,
46 pub channels: [ChannelState; 4],
47 pub decks: [DeckState; 4],
48}
49
50impl State {
51 pub fn apply_update(&mut self, update: StateUpdate) {
52 match update {
53 StateUpdate::Mixer(mixer) => self.mixer = mixer,
54 StateUpdate::Channel(id, channel) => self.channels[id as usize] = channel,
55 StateUpdate::DeckContent(id, deck_content) => {
56 self.decks[id as usize].content = *deck_content
57 }
58 StateUpdate::DeckPlayState(id, deck_play_state) => {
59 self.decks[id as usize].play_state = deck_play_state
60 }
61 }
62 }
63}
64
65impl<'de> Deserialize<'de> for State {
66 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
67 where
68 D: Deserializer<'de>,
69 {
70 #[derive(Deserialize)]
71 struct FlattenedState {
72 mixer: MixerState,
73 channel0: ChannelState,
74 channel1: ChannelState,
75 channel2: ChannelState,
76 channel3: ChannelState,
77 deck0content: DeckContentState,
78 deck1content: DeckContentState,
79 deck2content: DeckContentState,
80 deck3content: DeckContentState,
81 deck0playstate: DeckPlayState,
82 deck1playstate: DeckPlayState,
83 deck2playstate: DeckPlayState,
84 deck3playstate: DeckPlayState,
85 }
86
87 let flattened_state: FlattenedState = Deserialize::deserialize(deserializer)?;
88
89 Ok(State {
90 mixer: flattened_state.mixer,
91 channels: [
92 flattened_state.channel0,
93 flattened_state.channel1,
94 flattened_state.channel2,
95 flattened_state.channel3,
96 ],
97 decks: [
98 DeckState {
99 content: flattened_state.deck0content,
100 play_state: flattened_state.deck0playstate,
101 },
102 DeckState {
103 content: flattened_state.deck1content,
104 play_state: flattened_state.deck1playstate,
105 },
106 DeckState {
107 content: flattened_state.deck2content,
108 play_state: flattened_state.deck2playstate,
109 },
110 DeckState {
111 content: flattened_state.deck3content,
112 play_state: flattened_state.deck3playstate,
113 },
114 ],
115 })
116 }
117}
118
119#[derive(Debug, Deserialize, Clone, Copy)]
120#[serde(rename_all = "camelCase")]
121pub struct MixerState {
122 pub x_fader: f64,
123 pub master_volume: f64,
124 pub cue_volume: f64,
125 pub cue_mix: f64,
126 pub mic_volume: f64,
127}
128
129#[derive(Debug, Deserialize, Clone, Copy)]
130#[serde(rename_all = "camelCase")]
131pub struct ChannelState {
132 pub cue: bool,
133 pub volume: f64,
134 pub x_fader_left: bool,
135 pub x_fader_right: bool,
136}
137
138#[derive(Debug, Clone)]
139pub struct DeckState {
140 pub content: DeckContentState,
141 pub play_state: DeckPlayState,
142}
143
144#[derive(Debug, Deserialize, Clone)]
145#[serde(rename_all = "camelCase")]
146pub struct DeckContentState {
147 pub is_loaded: bool,
148
149 pub number: u32,
150 pub title: String,
151 pub artist: String,
152 pub album: String,
153 pub genre: String,
154 pub comment: String,
155 pub comment2: String,
156 pub label: String,
157
158 pub key: String,
159 pub file_path: String,
160 pub track_length: f64,
161 pub bpm: f64,
162}
163
164#[derive(Debug, Deserialize, Clone, Copy)]
165pub struct DeckPlayState {
166 pub timestamp: u64,
167 pub position: f64,
168 pub speed: f64,
169}
170
171#[derive(Debug, Serialize, Clone)]
172#[serde(rename_all = "camelCase")]
173pub(in crate::traktor_api) struct ConnectionResponse {
174 pub session_id: String,
175 pub debug_logging: bool,
176}
177
178#[derive(Debug, Deserialize, Clone)]
179#[serde(rename_all = "camelCase")]
180pub(in crate::traktor_api) struct InitializeRequest {
181 pub session_id: String,
182 pub timestamp: u64,
183 pub state: State,
184}
185
186#[derive(Debug, Deserialize, Clone)]
187#[serde(rename_all = "camelCase")]
188pub(in crate::traktor_api) struct UpdateRequest<T> {
189 pub session_id: String,
190 pub state: T,
191}