OXYGENHUB
# 19c71c828f86 oxygenhub / crates / hub-api / src / lib.rs
3.5 KiB · Rust · last changed Milestone 0.1: browse 1 month ago source blame history raw
d23464c0 Andy McCall ↶ 1
//! Types of the Oxygenhub JSON API (hub spec §12.1). Everything here is
2
//! `serde` data with no behaviour, so clients in other languages can be
3
//! generated from it and the server can never drift from them.
4
//!
5
//! Shapes reuse `oxy --json`'s where one exists (hashes as lowercase hex,
6
//! times as milliseconds since the epoch), so tools written against the
7
//! command line work against the hub.
8
9
use serde::{Deserialize, Serialize};
10
11
/// A repository as the API lists it.
12
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
13
pub struct Repository {
14
    pub owner: String,
15
    pub name: String,
16
    pub description: String,
17
    pub default_bookmark: String,
18
    pub visibility: Visibility,
19
    /// Milliseconds since the epoch.
20
    pub created_ms: i64,
21
    pub updated_ms: i64,
22
    /// `https://…/{owner}/{name}`, what `oxy clone` takes.
23
    pub clone_url: String,
24
}
25
26
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
27
#[serde(rename_all = "lowercase")]
28
pub enum Visibility {
29
    Public,
30
    Internal,
31
    Private,
32
}
33
34
impl Visibility {
35
    pub fn as_str(self) -> &'static str {
36
        match self {
37
            Visibility::Public => "public",
38
            Visibility::Internal => "internal",
39
            Visibility::Private => "private",
40
        }
41
    }
42
43
    pub fn parse(s: &str) -> Option<Visibility> {
44
        Some(match s {
45
            "public" => Visibility::Public,
46
            "internal" => Visibility::Internal,
47
            "private" => Visibility::Private,
48
            _ => return None,
49
        })
50
    }
51
}
52
53
/// A bookmark: a name for a set of heads (spec §10.1).
54
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
55
pub struct Bookmark {
56
    pub name: String,
57
    pub heads: Vec<String>,
58
    /// Number of changes in the bookmark's state.
59
    pub changes: usize,
60
    pub default: bool,
61
}
62
63
/// A tag: a name for one state, with its attestation when signed.
64
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
65
pub struct Tag {
66
    pub name: String,
67
    pub heads: Vec<String>,
68
    pub message: String,
69
    pub signer: Option<String>,
70
}
71
72
/// One change in a history listing.
73
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
74
pub struct ChangeSummary {
75
    pub hash: String,
76
    pub message: String,
77
    pub author: Author,
78
    pub when_ms: u64,
79
    pub deps: Vec<String>,
80
    pub head: bool,
81
    pub signature: Signature,
82
}
83
84
/// Who wrote a change: the linked account when the signing key is linked,
85
/// else the key alone.
86
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
87
pub struct Author {
88
    pub name: String,
89
    pub email: String,
90
    pub key: String,
91
    /// The hub account this key is linked to, when any.
92
    pub account: Option<String>,
93
}
94
95
/// Signature status of a change as `oxy verify` reports it.
96
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
97
#[serde(tag = "status", rename_all = "lowercase")]
98
pub enum Signature {
99
    Unsigned,
100
    Valid { key: String, sealed: bool, revoked: bool },
101
    Invalid { reason: String },
102
}
103
104
/// An RFC 7807 problem response.
105
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
106
pub struct Problem {
107
    pub status: u16,
108
    pub title: String,
109
    pub detail: String,
110
}
111
112
#[cfg(test)]
113
mod tests {
114
    use super::*;
115
116
    #[test]
117
    fn visibility_round_trips() {
118
        for v in [Visibility::Public, Visibility::Internal, Visibility::Private] {
119
            assert_eq!(Visibility::parse(v.as_str()), Some(v));
120
        }
121
        assert_eq!(Visibility::parse("secret"), None);
122
    }
123
}