Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic support for v14 #85

Merged
merged 6 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Possible log types:

- [added] The `Sensors`, `PeopleNowPresentSensor` and `TemperatureSensor`
structs now derive `Default` (#84)
- [added] Basic support for the new v14 API (#85) This is a breaking change since
it changes the `api` field of `Status` to `Option<String>`.

### v0.7.0 (2019-08-22)

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Crates.io Version](https://img.shields.io/crates/v/spaceapi.svg)](https://crates.io/crates/spaceapi)
[![Crates.io Downloads](https://img.shields.io/crates/d/spaceapi.svg)](https://crates.io/crates/spaceapi)

This is an implementation of the [SpaceAPI](https://spaceapi.io/) v0.13
This is an implementation of the [SpaceAPI](https://spaceapi.io/) v0.13 and v14
in Rust. It contains both the type definitions as well as tools for
serialization and deserialization to/from JSON using Serde.

Expand All @@ -19,7 +19,7 @@ This library requires Rust 1.31.0 or newer.
Add `spaceapi` to your `Cargo.toml`:

[dependencies]
spaceapi = "^0.5"
spaceapi = "^0.7"


## Docs
Expand Down
2 changes: 1 addition & 1 deletion examples/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde_json;
use spaceapi::{Contact, IssueReportChannel, Location, StatusBuilder};

fn main() {
let status = StatusBuilder::new("coredump")
let status = StatusBuilder::mixed("coredump")
.logo("https://www.coredump.ch/logo.png")
.url("https://www.coredump.ch/")
.location(Location {
Expand Down
68 changes: 63 additions & 5 deletions src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,22 @@ pub struct Stream {
pub ustream: Option<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum ApiVersion {
#[serde(rename = "14")]
V14,
}

/// The main SpaceAPI status object.
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)]
pub struct Status {
// Hackerspace properties
pub api: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub api: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub api_compatibility: Option<Vec<ApiVersion>>,

pub space: String,
pub logo: String,
pub url: String,
Expand Down Expand Up @@ -214,7 +225,7 @@ impl Status {
issue_report_channels: Vec<IssueReportChannel>,
) -> Status {
Status {
api: "0.13".into(),
api: Some("0.13".into()),
space: space.into(),
logo: logo.into(),
url: url.into(),
Expand All @@ -226,9 +237,23 @@ impl Status {
}
}

#[derive(Debug, Clone)]
enum StatusBuilderVersion {
V0_13,
V14,
Mixed,
}

impl Default for StatusBuilderVersion {
fn default() -> StatusBuilderVersion {
StatusBuilderVersion::V0_13
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does a default impl for the version make sense? I'd rather remove the Default derive from StatusBuilder.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well it would make constructing StatusBuilder a lot more annoying since one would need to specify all the fields (see new(), v0_13(), v14() currently line 273.
If we remove Default I'd also remove the new constructor.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, true. But from a user perspective, as long as we use the constructor methods, it shouldn't be an issue, right?


/// Builder for the `Status` object.
#[derive(Default, Debug, Clone)]
pub struct StatusBuilder {
version: StatusBuilderVersion,
space: String,
logo: Option<String>,
url: Option<String>,
Expand All @@ -252,6 +277,30 @@ impl StatusBuilder {
}
}

pub fn v0_13<S: Into<String>>(space_name: S) -> StatusBuilder {
StatusBuilder {
space: space_name.into(),
version: StatusBuilderVersion::V0_13,
..Default::default()
}
}

pub fn v14<S: Into<String>>(space_name: S) -> StatusBuilder {
StatusBuilder {
space: space_name.into(),
version: StatusBuilderVersion::V14,
..Default::default()
}
}

pub fn mixed<S: Into<String>>(space_name: S) -> StatusBuilder {
StatusBuilder {
space: space_name.into(),
version: StatusBuilderVersion::Mixed,
..Default::default()
}
}

pub fn logo<S: Into<String>>(mut self, logo: S) -> Self {
self.logo = Some(logo.into());
self
Expand Down Expand Up @@ -320,8 +369,17 @@ impl StatusBuilder {
}

pub fn build(self) -> Result<Status, String> {
let api = match self.version {
StatusBuilderVersion::V0_13 | StatusBuilderVersion::Mixed => Some("0.13".to_owned()),
_ => None,
};
let api_compatibility = match self.version {
StatusBuilderVersion::V14 | StatusBuilderVersion::Mixed => Some(vec![ApiVersion::V14]),
_ => None,
};
Ok(Status {
api: "0.13".into(), // TODO: Deduplicate
api,
api_compatibility,
space: self.space,
logo: self.logo.ok_or("logo missing")?,
url: self.url.ok_or("url missing")?,
Expand Down Expand Up @@ -392,7 +450,7 @@ mod test {
.add_issue_report_channel(IssueReportChannel::Email)
.build()
.unwrap();
assert_eq!(status.api, "0.13");
assert_eq!(status.api, Some("0.13".into()));
assert_eq!(status.space, "foo");
assert_eq!(status.logo, "bar");
assert_eq!(status.url, "foobar");
Expand Down Expand Up @@ -525,7 +583,7 @@ mod test {
\"location\":{\"lat\":0.0,\"lon\":0.0},\"contact\":{},\"issue_report_channels\":[],\
\"state\":{\"open\":null},\"ext_aaa\":\"xxx\",\"ext_bbb\":[null,42]}";
let deserialized: Status = from_str(&data).unwrap();
assert_eq!(&deserialized.api, "0.13");
assert_eq!(deserialized.api, Some("0.13".into()));
let keys: Vec<_> = deserialized.extensions.keys().collect();
assert_eq!(keys.len(), 2)
}
Expand Down