librespot_metadata/playlist/
operation.rs1use std::{
2 fmt::Debug,
3 ops::{Deref, DerefMut},
4};
5
6use crate::{
7 playlist::{
8 attribute::{PlaylistUpdateAttributes, PlaylistUpdateItemAttributes},
9 item::PlaylistItems,
10 },
11 util::{impl_deref_wrapped, impl_try_from_repeated},
12};
13
14use librespot_protocol as protocol;
15use protocol::playlist4_external::Add as PlaylistAddMessage;
16use protocol::playlist4_external::Mov as PlaylistMoveMessage;
17use protocol::playlist4_external::Op as PlaylistOperationMessage;
18use protocol::playlist4_external::Rem as PlaylistRemoveMessage;
19pub use protocol::playlist4_external::op::Kind as PlaylistOperationKind;
20
21#[derive(Debug, Clone)]
22pub struct PlaylistOperation {
23 pub kind: PlaylistOperationKind,
24 pub add: PlaylistOperationAdd,
25 pub rem: PlaylistOperationRemove,
26 pub mov: PlaylistOperationMove,
27 pub update_item_attributes: PlaylistUpdateItemAttributes,
28 pub update_list_attributes: PlaylistUpdateAttributes,
29}
30
31#[derive(Debug, Clone, Default)]
32pub struct PlaylistOperations(pub Vec<PlaylistOperation>);
33
34impl_deref_wrapped!(PlaylistOperations, Vec<PlaylistOperation>);
35
36#[derive(Debug, Clone)]
37pub struct PlaylistOperationAdd {
38 pub from_index: i32,
39 pub items: PlaylistItems,
40 pub add_last: bool,
41 pub add_first: bool,
42}
43
44#[derive(Debug, Clone)]
45pub struct PlaylistOperationMove {
46 pub from_index: i32,
47 pub length: i32,
48 pub to_index: i32,
49}
50
51#[derive(Debug, Clone)]
52pub struct PlaylistOperationRemove {
53 pub from_index: i32,
54 pub length: i32,
55 pub items: PlaylistItems,
56 pub has_items_as_key: bool,
57}
58
59impl TryFrom<&PlaylistOperationMessage> for PlaylistOperation {
60 type Error = librespot_core::Error;
61 fn try_from(operation: &PlaylistOperationMessage) -> Result<Self, Self::Error> {
62 Ok(Self {
63 kind: operation.kind(),
64 add: operation.add.get_or_default().try_into()?,
65 rem: operation.rem.get_or_default().try_into()?,
66 mov: operation.mov.get_or_default().into(),
67 update_item_attributes: operation
68 .update_item_attributes
69 .get_or_default()
70 .try_into()?,
71 update_list_attributes: operation
72 .update_list_attributes
73 .get_or_default()
74 .try_into()?,
75 })
76 }
77}
78
79impl_try_from_repeated!(PlaylistOperationMessage, PlaylistOperations);
80
81impl TryFrom<&PlaylistAddMessage> for PlaylistOperationAdd {
82 type Error = librespot_core::Error;
83 fn try_from(add: &PlaylistAddMessage) -> Result<Self, Self::Error> {
84 Ok(Self {
85 from_index: add.from_index(),
86 items: add.items.as_slice().try_into()?,
87 add_last: add.add_last(),
88 add_first: add.add_first(),
89 })
90 }
91}
92
93impl From<&PlaylistMoveMessage> for PlaylistOperationMove {
94 fn from(mov: &PlaylistMoveMessage) -> Self {
95 Self {
96 from_index: mov.from_index(),
97 length: mov.length(),
98 to_index: mov.to_index(),
99 }
100 }
101}
102
103impl TryFrom<&PlaylistRemoveMessage> for PlaylistOperationRemove {
104 type Error = librespot_core::Error;
105 fn try_from(remove: &PlaylistRemoveMessage) -> Result<Self, Self::Error> {
106 Ok(Self {
107 from_index: remove.from_index(),
108 length: remove.length(),
109 items: remove.items.as_slice().try_into()?,
110 has_items_as_key: remove.items_as_key(),
111 })
112 }
113}