Skip to main content

yt/api/
parent.rs

1use serde::Deserialize;
2use url::Url;
3
4use crate::api::{Client, Projection};
5use crate::error::Result;
6use crate::instance::InstanceUrl;
7
8/// What comments and attachments belong to, by readable ID.
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub enum Parent {
11    Issue(String),
12    Article(String),
13}
14
15impl Parent {
16    pub fn id(&self) -> &str {
17        match self {
18            Self::Issue(id) | Self::Article(id) => id,
19        }
20    }
21
22    /// The REST path of the issue or article: `issues/WEB-1`, `articles/KB-A-1`.
23    pub fn path(&self) -> String {
24        match self {
25            Self::Issue(id) => format!("issues/{id}"),
26            Self::Article(id) => format!("articles/{id}"),
27        }
28    }
29
30    pub fn url(&self, instance: &InstanceUrl) -> Url {
31        match self {
32            Self::Issue(id) => instance.issue_url(id),
33            Self::Article(id) => instance.article_url(id),
34        }
35    }
36
37    pub fn noun(&self) -> &'static str {
38        match self {
39            Self::Issue(_) => "issue",
40            Self::Article(_) => "article",
41        }
42    }
43}
44
45#[derive(Deserialize)]
46struct Found {}
47
48impl Projection for Found {
49    const FIELDS: &'static str = "id";
50}
51
52/// Fails unless the issue or article exists; checked before opening an editor so no writing is lost.
53pub async fn exists(client: &Client, parent: &Parent) -> Result<()> {
54    client.get::<Found>(&parent.path(), &[]).await.map(drop)
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn parents_name_their_paths_and_pages() {
63        let instance = InstanceUrl::parse("https://acme.youtrack.cloud").unwrap();
64        let issue = Parent::Issue("WEB-1".into());
65        let article = Parent::Article("KB-A-1".into());
66        assert_eq!(issue.path(), "issues/WEB-1");
67        assert_eq!(article.path(), "articles/KB-A-1");
68        assert_eq!(article.id(), "KB-A-1");
69        assert_eq!(issue.noun(), "issue");
70        assert_eq!(
71            article.url(&instance).as_str(),
72            "https://acme.youtrack.cloud/articles/KB-A-1"
73        );
74    }
75}