Skip to content

Commit e3e60bb

Browse files
committed
Use serde for requests/responses of discovery server
Adds the modules `request` and `response` to `librespot_discovery`, which contain structs implementing `serde::{Deserialize, Serialize}` in order to parse requests and create responses.
1 parent 1f13fc7 commit e3e60bb

File tree

7 files changed

+1037
-115
lines changed

7 files changed

+1037
-115
lines changed

Cargo.lock

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/config.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
use std::convert::TryFrom;
12
use std::fmt;
23
use std::str::FromStr;
4+
5+
use serde::{Deserialize, Serialize};
36
use url::Url;
47

58
#[derive(Clone, Debug)]
@@ -22,7 +25,9 @@ impl Default for SessionConfig {
2225
}
2326
}
2427

25-
#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
28+
#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
29+
#[serde(into = "&str")]
30+
#[serde(try_from = "String")]
2631
pub enum DeviceType {
2732
Unknown = 0,
2833
Computer = 1,
@@ -71,6 +76,14 @@ impl FromStr for DeviceType {
7176
}
7277
}
7378

79+
impl TryFrom<String> for DeviceType {
80+
type Error = &'static str;
81+
82+
fn try_from(value: String) -> Result<Self, Self::Error> {
83+
value.parse().map_err(|_| "Invalid device type")
84+
}
85+
}
86+
7487
impl From<&DeviceType> for &str {
7588
fn from(d: &DeviceType) -> &'static str {
7689
use self::DeviceType::*;

discovery/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ hyper = { version = "0.14", features = ["server", "http1", "tcp"] }
1818
libmdns = "0.6"
1919
log = "0.4"
2020
rand = "0.8"
21-
serde_json = "1.0.25"
21+
serde = { version = "1.0", features = ["derive"] }
22+
serde_json = "1.0"
23+
serde_urlencoded = "0.7"
2224
sha-1 = "0.9"
2325
tokio = { version = "1.0", features = ["sync", "rt"] }
2426

discovery/src/lib.rs

+39-25
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,21 @@
66
77
#![warn(clippy::all, missing_docs, rust_2018_idioms)]
88

9+
mod request;
10+
mod response;
911
mod server;
1012

13+
mod util {
14+
use hyper::{Body, Response, StatusCode};
15+
16+
#[inline]
17+
pub fn new_response(status: StatusCode, body: impl Into<Body>) -> Response<Body> {
18+
let mut response = Response::new(body.into());
19+
*response.status_mut() = status;
20+
response
21+
}
22+
}
23+
1124
use std::io;
1225
use std::pin::Pin;
1326
use std::task::{Context, Poll};
@@ -39,32 +52,32 @@ pub struct Discovery {
3952

4053
/// A builder for [`Discovery`].
4154
pub struct Builder {
42-
server_config: server::Config,
55+
name: String,
56+
device_id: String,
57+
device_type: DeviceType,
4358
port: u16,
4459
}
4560

4661
impl Builder {
4762
/// Starts a new builder using the provided device id.
4863
pub fn new(device_id: String) -> Self {
4964
Self {
50-
server_config: server::Config {
51-
name: "Librespot".into(),
52-
device_type: DeviceType::default(),
53-
device_id,
54-
},
65+
name: "Librespot".into(),
66+
device_type: DeviceType::default(),
67+
device_id,
5568
port: 0,
5669
}
5770
}
5871

5972
/// Sets the name to be displayed. Default is `"Librespot"`.
6073
pub fn name(mut self, name: String) -> Self {
61-
self.server_config.name = name.into();
74+
self.name = name;
6275
self
6376
}
6477

6578
/// Sets the device type which is visible as icon in other Spotify clients. Default is `Speaker`.
6679
pub fn device_type(mut self, device_type: DeviceType) -> Self {
67-
self.server_config.device_type = device_type;
80+
self.device_type = device_type;
6881
self
6982
}
7083

@@ -80,28 +93,17 @@ impl Builder {
8093
/// # Errors
8194
/// If setting up the mdns service or creating the server fails, this function returns an error.
8295
pub fn launch(self) -> io::Result<Discovery> {
83-
Discovery::new(self)
84-
}
85-
}
86-
87-
impl Discovery {
88-
/// Starts a [`Builder`] with the provided device id.
89-
pub fn builder(device_id: String) -> Builder {
90-
Builder::new(device_id)
91-
}
92-
93-
fn new(builder: Builder) -> io::Result<Self> {
94-
let name = builder.server_config.name.clone();
95-
let mut port = builder.port;
96-
let server = DiscoveryServer::new(builder.server_config, &mut port)
96+
let name = self.name.clone();
97+
let mut port = self.port;
98+
let server = DiscoveryServer::new(self.name, self.device_type, self.device_id, &mut port)
9799
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
98100

99101
let svc;
100102

101103
cfg_if! {
102104
if #[cfg(feature = "with-dns-sd")] {
103105
svc = dns_sd::DNSService::register(
104-
Some(name.as_ref()),
106+
Some(&name),
105107
"_spotify-connect._tcp",
106108
None,
107109
None,
@@ -114,14 +116,26 @@ impl Discovery {
114116
let responder = libmdns::Responder::spawn(&tokio::runtime::Handle::current())?;
115117
svc = responder.register(
116118
"_spotify-connect._tcp".to_owned(),
117-
name.into_owned(),
119+
name,
118120
port,
119121
&["VERSION=1.0", "CPath=/"],
120122
)
121123
}
122124
};
123125

124-
Ok(Self { server, _svc: svc })
126+
Ok(Discovery { server, _svc: svc })
127+
}
128+
}
129+
130+
impl Discovery {
131+
/// Starts a [`Builder`] with the provided device id.
132+
pub fn builder(device_id: String) -> Builder {
133+
Builder::new(device_id)
134+
}
135+
136+
/// Create a new instance with the specified device id and default paramaters.
137+
pub fn new(device_id: String) -> io::Result<Self> {
138+
Self::builder(device_id).launch()
125139
}
126140
}
127141

0 commit comments

Comments
 (0)