///| GitHub API response types with JSON parsing
///|
/// GitHub Issue from REST API
pub struct GhIssue {
number : Int
node_id : String
title : String
body : String
state : String
user : String
labels : Array[String]
assignees : Array[String]
created_at : String
updated_at : String
}
///|
/// GitHub Pull Request from REST API
pub struct GhPullRequest {
number : Int
node_id : String
title : String
body : String
state : String
user : String
head_ref : String
head_repo : String
base_ref : String
labels : Array[String]
created_at : String
updated_at : String
merged : Bool
merged_at : String
}
///|
/// GitHub Comment from REST API
pub struct GhComment {
id : Int
node_id : String
body : String
user : String
created_at : String
updated_at : String
}
///|
fn gh_json_string(
obj : Map[String, Json],
key : String,
fallback : String,
) -> String {
match obj.get(key) {
Some(Json::String(value)) => value
Some(Json::Number(value, ..)) => value.to_string()
Some(Json::True) => "true"
Some(Json::False) => "false"
_ => fallback
}
}
///|
fn gh_json_int(obj : Map[String, Json], key : String, fallback : Int) -> Int {
match obj.get(key) {
Some(Json::Number(value, ..)) => value.to_int()
_ => fallback
}
}
///|
fn gh_json_nested_string(
obj : Map[String, Json],
key : String,
nested_key : String,
fallback : String,
) -> String {
match obj.get(key) {
Some(Json::Object(inner)) => gh_json_string(inner, nested_key, fallback)
_ => fallback
}
}
///|
fn gh_json_array_of_nested_strings(
obj : Map[String, Json],
key : String,
nested_key : String,
) -> Array[String] {
match obj.get(key) {
Some(Json::Array(items)) => {
let out : Array[String] = []
for item in items {
match item {
Json::Object(inner) =>
match inner.get(nested_key) {
Some(Json::String(value)) => out.push(value)
_ => ()
}
_ => ()
}
}
out
}
_ => []
}
}
///|
fn gh_json_bool(obj : Map[String, Json], key : String, fallback : Bool) -> Bool {
match obj.get(key) {
Some(Json::True) => true
Some(Json::False) => false
_ => fallback
}
}
///|
pub fn GhIssue::from_json(obj : Map[String, Json]) -> GhIssue {
{
number: gh_json_int(obj, "number", 0),
node_id: gh_json_string(obj, "node_id", ""),
title: gh_json_string(obj, "title", ""),
body: gh_json_string(obj, "body", ""),
state: gh_json_string(obj, "state", ""),
user: gh_json_nested_string(obj, "user", "login", ""),
labels: gh_json_array_of_nested_strings(obj, "labels", "name"),
assignees: gh_json_array_of_nested_strings(obj, "assignees", "login"),
created_at: gh_json_string(obj, "created_at", ""),
updated_at: gh_json_string(obj, "updated_at", ""),
}
}
///|
pub fn GhPullRequest::from_json(obj : Map[String, Json]) -> GhPullRequest {
let merged = gh_json_bool(obj, "merged", false)
let state = if merged { "merged" } else { gh_json_string(obj, "state", "") }
let head_repo = match obj.get("head") {
Some(Json::Object(head)) =>
match head.get("repo") {
Some(Json::Object(repo)) => gh_json_string(repo, "full_name", "")
_ => ""
}
_ => ""
}
{
number: gh_json_int(obj, "number", 0),
node_id: gh_json_string(obj, "node_id", ""),
title: gh_json_string(obj, "title", ""),
body: gh_json_string(obj, "body", ""),
state,
user: gh_json_nested_string(obj, "user", "login", ""),
head_ref: gh_json_nested_string(obj, "head", "ref", ""),
head_repo,
base_ref: gh_json_nested_string(obj, "base", "ref", ""),
labels: gh_json_array_of_nested_strings(obj, "labels", "name"),
created_at: gh_json_string(obj, "created_at", ""),
updated_at: gh_json_string(obj, "updated_at", ""),
merged,
merged_at: gh_json_string(obj, "merged_at", ""),
}
}
///|
pub fn GhComment::from_json(obj : Map[String, Json]) -> GhComment {
{
id: gh_json_int(obj, "id", 0),
node_id: gh_json_string(obj, "node_id", ""),
body: gh_json_string(obj, "body", ""),
user: gh_json_nested_string(obj, "user", "login", ""),
created_at: gh_json_string(obj, "created_at", ""),
updated_at: gh_json_string(obj, "updated_at", ""),
}
}