Skip to content

Commit

Permalink
Merge pull request #85 from spaceapi-community/support-0.14
Browse files Browse the repository at this point in the history
Add basic support for v14
  • Loading branch information
rnestler authored Nov 16, 2020
2 parents c27501b + 459bc78 commit 001cefb
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 8 deletions.
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
116 changes: 111 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
}
}

/// 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 @@ -376,6 +434,54 @@ mod test {
assert_eq!(a, b);
}

#[test]
fn test_builder_v14() {
let status = StatusBuilder::v14("foo")
.logo("bar")
.url("foobar")
.location(Location::default())
.contact(Contact::default())
.add_issue_report_channel(IssueReportChannel::Email)
.build()
.unwrap();
assert_eq!(
status,
Status {
api: None,
api_compatibility: Some(vec![ApiVersion::V14]),
space: "foo".into(),
logo: "bar".into(),
url: "foobar".into(),
issue_report_channels: vec![IssueReportChannel::Email],
..Status::default()
}
);
}

#[test]
fn test_builder_mixed() {
let status = StatusBuilder::mixed("foo")
.logo("bar")
.url("foobar")
.location(Location::default())
.contact(Contact::default())
.add_issue_report_channel(IssueReportChannel::Email)
.build()
.unwrap();
assert_eq!(
status,
Status {
api: Some("0.13".into()),
api_compatibility: Some(vec![ApiVersion::V14]),
space: "foo".into(),
logo: "bar".into(),
url: "foobar".into(),
issue_report_channels: vec![IssueReportChannel::Email],
..Status::default()
}
);
}

#[test]
fn test_builder() {
let status = StatusBuilder::new("foo")
Expand All @@ -392,7 +498,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 +631,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

0 comments on commit 001cefb

Please sign in to comment.