feat(papermc_api): add routes for per-version, project and build information
This commit is contained in:
parent
b4dce4b69a
commit
f2c4b97626
2 changed files with 111 additions and 68 deletions
|
|
@ -1,9 +1,8 @@
|
|||
use serde_json::Value;
|
||||
|
||||
use crate::{
|
||||
error::Error,
|
||||
models::{Build, BuildCommit, BuildDownload, Java, Project, Version},
|
||||
};
|
||||
pub use error::Error;
|
||||
|
||||
use crate::models::{Build, BuildCommit, BuildDownload, Java, Project, Version};
|
||||
|
||||
mod error;
|
||||
mod models;
|
||||
|
|
@ -26,33 +25,7 @@ impl Client {
|
|||
let body_json: Value = res.body_mut().read_json()?;
|
||||
|
||||
let projects = body_json["projects"].as_array().ok_or(Error::BadBody)?;
|
||||
projects
|
||||
.into_iter()
|
||||
.map(|p| {
|
||||
Ok(Project {
|
||||
id: p["project"]["id"]
|
||||
.as_str()
|
||||
.map(|s| s.to_string())
|
||||
.ok_or(Error::BadBody)?,
|
||||
name: p["project"]["name"]
|
||||
.as_str()
|
||||
.map(|s| s.to_string())
|
||||
.ok_or(Error::BadBody)?,
|
||||
// Flatten map of versions into one array
|
||||
versions: p["versions"]
|
||||
.as_object()
|
||||
.ok_or(Error::BadBody)?
|
||||
.into_iter()
|
||||
.map(|(_, versions)| versions.as_array().ok_or(Error::BadBody))
|
||||
// Collect into error to propagate error of any of the versions
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|v| v.as_str().ok_or(Error::BadBody).map(|s| s.to_string()))
|
||||
.collect::<Result<_, _>>()?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
projects.into_iter().map(parse_project_json).collect()
|
||||
}
|
||||
|
||||
pub fn project<'a>(&'a self, project: &'a str) -> ProjectQuery<'a> {
|
||||
|
|
@ -69,6 +42,16 @@ pub struct ProjectQuery<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ProjectQuery<'a> {
|
||||
pub fn info(&self) -> Result<Project, Error> {
|
||||
let mut res = self
|
||||
.agent
|
||||
.get(format!("{}/projects/{}", BASE_URL, self.project))
|
||||
.call()?;
|
||||
let body_json: Value = res.body_mut().read_json()?;
|
||||
|
||||
parse_project_json(&body_json)
|
||||
}
|
||||
|
||||
pub fn versions(&self) -> Result<Vec<Version>, Error> {
|
||||
let mut res = self
|
||||
.agent
|
||||
|
|
@ -77,39 +60,7 @@ impl<'a> ProjectQuery<'a> {
|
|||
let body_json: Value = res.body_mut().read_json()?;
|
||||
|
||||
let versions = body_json["versions"].as_array().ok_or(Error::BadBody)?;
|
||||
versions
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
Ok(Version {
|
||||
id: v["version"]["id"]
|
||||
.as_str()
|
||||
.map(String::from)
|
||||
.ok_or(Error::BadBody)?,
|
||||
support_status: v["version"]["support"]["status"]
|
||||
.as_str()
|
||||
.ok_or(Error::BadBody)?
|
||||
.parse()
|
||||
.map_err(|_| Error::BadBody)?,
|
||||
java: Java {
|
||||
minimum_version: v["version"]["java"]["version"]["minimum"]
|
||||
.as_u64()
|
||||
.ok_or(Error::BadBody)?,
|
||||
recommended_flags: v["version"]["java"]["flags"]["recommended"]
|
||||
.as_array()
|
||||
.ok_or(Error::BadBody)?
|
||||
.into_iter()
|
||||
.map(|v| v.as_str().map(String::from).ok_or(Error::BadBody))
|
||||
.collect::<Result<_, _>>()?,
|
||||
},
|
||||
builds: v["builds"]
|
||||
.as_array()
|
||||
.ok_or(Error::BadBody)?
|
||||
.into_iter()
|
||||
.map(|v| v.as_u64().ok_or(Error::BadBody))
|
||||
.collect::<Result<_, _>>()?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
versions.into_iter().map(parse_version_json).collect()
|
||||
}
|
||||
|
||||
pub fn version(&self, version: &'a str) -> VersionQuery<'a> {
|
||||
|
|
@ -128,17 +79,17 @@ pub struct VersionQuery<'a> {
|
|||
}
|
||||
|
||||
impl<'a> VersionQuery<'a> {
|
||||
pub fn latest(&self) -> Result<Build, Error> {
|
||||
pub fn info(&self) -> Result<Version, Error> {
|
||||
let mut res = self
|
||||
.agent
|
||||
.get(format!(
|
||||
"{}/projects/{}/versions/{}/builds/latest",
|
||||
"{}/projects/{}/versions/{}",
|
||||
BASE_URL, self.project, self.version
|
||||
))
|
||||
.call()?;
|
||||
let body_json: Value = res.body_mut().read_json()?;
|
||||
|
||||
parse_build_json(&body_json)
|
||||
parse_version_json(&body_json)
|
||||
}
|
||||
|
||||
pub fn builds(&self) -> Result<Vec<Build>, Error> {
|
||||
|
|
@ -158,6 +109,79 @@ impl<'a> VersionQuery<'a> {
|
|||
.map(parse_build_json)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn build(&self, build: &str) -> Result<Build, Error> {
|
||||
let mut res = self
|
||||
.agent
|
||||
.get(format!(
|
||||
"{}/projects/{}/versions/{}/builds/{}",
|
||||
BASE_URL, self.project, self.version, build
|
||||
))
|
||||
.call()?;
|
||||
let body_json: Value = res.body_mut().read_json()?;
|
||||
|
||||
parse_build_json(&body_json)
|
||||
}
|
||||
|
||||
pub fn latest(&self) -> Result<Build, Error> {
|
||||
return self.build("latest");
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_project_json(value: &Value) -> Result<Project, Error> {
|
||||
Ok(Project {
|
||||
id: value["project"]["id"]
|
||||
.as_str()
|
||||
.map(|s| s.to_string())
|
||||
.ok_or(Error::BadBody)?,
|
||||
name: value["project"]["name"]
|
||||
.as_str()
|
||||
.map(|s| s.to_string())
|
||||
.ok_or(Error::BadBody)?,
|
||||
// Flatten map of versions into one array
|
||||
versions: value["versions"]
|
||||
.as_object()
|
||||
.ok_or(Error::BadBody)?
|
||||
.into_iter()
|
||||
.map(|(_, versions)| versions.as_array().ok_or(Error::BadBody))
|
||||
// Collect into error to propagate error of any of the versions
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|v| v.as_str().ok_or(Error::BadBody).map(|s| s.to_string()))
|
||||
.collect::<Result<_, _>>()?,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_version_json(value: &Value) -> Result<Version, Error> {
|
||||
Ok(Version {
|
||||
id: value["version"]["id"]
|
||||
.as_str()
|
||||
.map(String::from)
|
||||
.ok_or(Error::BadBody)?,
|
||||
support_status: value["version"]["support"]["status"]
|
||||
.as_str()
|
||||
.ok_or(Error::BadBody)?
|
||||
.parse()
|
||||
.map_err(|_| Error::BadBody)?,
|
||||
java: Java {
|
||||
minimum_version: value["version"]["java"]["version"]["minimum"]
|
||||
.as_u64()
|
||||
.ok_or(Error::BadBody)?,
|
||||
recommended_flags: value["version"]["java"]["flags"]["recommended"]
|
||||
.as_array()
|
||||
.ok_or(Error::BadBody)?
|
||||
.into_iter()
|
||||
.map(|v| v.as_str().map(String::from).ok_or(Error::BadBody))
|
||||
.collect::<Result<_, _>>()?,
|
||||
},
|
||||
builds: value["builds"]
|
||||
.as_array()
|
||||
.ok_or(Error::BadBody)?
|
||||
.into_iter()
|
||||
.map(|v| v.as_u64().ok_or(Error::BadBody))
|
||||
.collect::<Result<_, _>>()?,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_build_json(value: &Value) -> Result<Build, Error> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{collections::HashMap, str::FromStr};
|
||||
use std::{collections::HashMap, fmt::Display, str::FromStr};
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
|
|
@ -29,6 +29,15 @@ impl FromStr for SupportStatus {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for SupportStatus {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Supported => f.write_str("SUPPORTED"),
|
||||
Self::Unsupported => f.write_str("UNSUPPORTED"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Java {
|
||||
pub minimum_version: u64,
|
||||
|
|
@ -74,6 +83,16 @@ impl FromStr for BuildChannel {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for BuildChannel {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Alpha => f.write_str("ALPHA"),
|
||||
Self::Beta => f.write_str("BETA"),
|
||||
Self::Stable => f.write_str("STABLE"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BuildCommit {
|
||||
pub sha: String,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue