Skip to main content

ephemeris_forge_forgejo/api/model/
repository.rs

1use facet::Facet;
2
3/// The built-in issue tracker settings as Forgejo reports them.
4#[derive(Clone, Copy, Debug, Default, Eq, Facet, PartialEq)]
5pub struct InternalTracker {
6    /// Whether time tracking is enabled.
7    pub enable_time_tracker: Option<bool>,
8    /// Whether only contributors may track time.
9    pub allow_only_contributors_to_track_time: Option<bool>,
10    /// Whether issues and pull requests may depend on each other.
11    pub enable_issue_dependencies: Option<bool>,
12}
13
14/// The external issue tracker settings as Forgejo reports them.
15#[derive(Clone, Debug, Default, Eq, Facet, PartialEq)]
16pub struct ExternalTracker {
17    /// The URL of the tracker.
18    pub external_tracker_url: Option<String>,
19    /// The issue URL format.
20    pub external_tracker_format: Option<String>,
21    /// How the tracker numbers its issues.
22    pub external_tracker_style: Option<String>,
23    /// The expression that finds issues when the style is `regexp`.
24    pub external_tracker_regexp_pattern: Option<String>,
25}
26
27/// The external wiki settings as Forgejo reports them.
28#[derive(Clone, Debug, Default, Eq, Facet, PartialEq)]
29pub struct ExternalWiki {
30    /// The URL of the wiki.
31    pub external_wiki_url: Option<String>,
32}
33
34/// What the authenticated caller may do with the repository.
35#[derive(Clone, Copy, Debug, Default, Eq, Facet, PartialEq)]
36pub struct ViewerPermissions {
37    /// Whether the caller administers the repository.
38    pub admin: Option<bool>,
39}
40
41/// The subset of the `Repository` response the CLI reads.
42///
43/// The type is open in both directions. Unknown properties are ignored, so a
44/// newer Forgejo still parses, and every known property is optional, so a
45/// dropped or null property reads as absent rather than failing the request.
46///
47/// `default_merge_style` and `default_update_style` stay `String`. Forgejo
48/// accepts values such as `manually-merged`, and a closed enum would fail the
49/// whole listing over a single repository that uses one.
50#[derive(Clone, Debug, Default, Facet)]
51pub struct Repository {
52    /// The repository's slug.
53    pub name: Option<String>,
54    /// The one-line summary shown on the repository's landing page.
55    pub description: Option<String>,
56    /// Topic labels used for discovery and filtering.
57    pub topics: Option<Vec<String>>,
58    /// Whether the repository rejects writes because it is archived.
59    pub archived: Option<bool>,
60    /// Needed to report the effective protection of the managed repository's
61    /// default branch.
62    pub default_branch: Option<String>,
63    /// Whether a merge is rejected unless the branch can fast-forward.
64    pub allow_fast_forward_only_merge: Option<bool>,
65    /// Whether merging is allowed to create a merge commit.
66    pub allow_merge_commits: Option<bool>,
67    /// Whether merging is allowed to rebase commits onto the base branch.
68    pub allow_rebase: Option<bool>,
69    /// Whether rebase merges may be done with an explicit merge commit.
70    pub allow_rebase_explicit: Option<bool>,
71    /// Whether a pull request branch may be updated by rebasing it.
72    pub allow_rebase_update: Option<bool>,
73    /// Whether merging is allowed to squash commits into one.
74    pub allow_squash_merge: Option<bool>,
75    /// Whether the source branch is deleted automatically after merging.
76    pub default_delete_branch_after_merge: Option<bool>,
77    /// The merge strategy preselected in the merge dialog.
78    pub default_merge_style: Option<String>,
79    /// The strategy preselected for updating an out-of-date pull request.
80    pub default_update_style: Option<String>,
81    /// Whether CI/CD actions are enabled.
82    pub has_actions: Option<bool>,
83    /// Whether the issue tracker is enabled.
84    pub has_issues: Option<bool>,
85    /// Whether the package registry is enabled.
86    pub has_packages: Option<bool>,
87    /// Whether project boards are enabled.
88    pub has_projects: Option<bool>,
89    /// Whether pull requests are enabled.
90    pub has_pull_requests: Option<bool>,
91    /// Whether releases are enabled.
92    pub has_releases: Option<bool>,
93    /// Whether the wiki is enabled.
94    pub has_wiki: Option<bool>,
95    /// The URL with more information about the repository.
96    pub website: Option<String>,
97    /// Whether the repository is private.
98    pub private: Option<bool>,
99    /// Whether the repository is a template.
100    pub template: Option<bool>,
101    /// The built-in issue tracker. Absent unless that tracker is in use.
102    pub internal_tracker: Option<InternalTracker>,
103    /// The external issue tracker. Absent unless that tracker is in use.
104    pub external_tracker: Option<ExternalTracker>,
105    /// The external wiki. Absent unless that wiki is in use.
106    pub external_wiki: Option<ExternalWiki>,
107    /// Whether whitespace is ignored when checking pull requests for
108    /// conflicts.
109    pub ignore_whitespace_conflicts: Option<bool>,
110    /// Whether maintainers may edit pull requests by default.
111    pub default_allow_maintainer_edit: Option<bool>,
112    /// Whether anyone with write access may edit the wiki.
113    pub globally_editable_wiki: Option<bool>,
114    /// The branch that holds the wiki.
115    pub wiki_branch: Option<String>,
116    /// Whether the repository is a pull mirror.
117    pub mirror: Option<bool>,
118    /// The mirror sync interval.
119    pub mirror_interval: Option<String>,
120    /// What the authenticated caller may do. Absent for anonymous reads.
121    pub permissions: Option<ViewerPermissions>,
122}
123
124#[cfg(test)]
125mod tests {
126    use super::Repository;
127
128    #[test]
129    fn unknown_properties_are_ignored() {
130        let raw = r#"{"has_wiki": true, "a_property_from_the_future": 42}"#;
131        let repo: Repository = facet_json::from_str(raw).expect("parses");
132        assert_eq!(repo.has_wiki, Some(true));
133    }
134
135    #[test]
136    fn an_unusual_merge_style_still_parses() {
137        let raw = r#"{"default_merge_style": "manually-merged"}"#;
138        let repo: Repository = facet_json::from_str(raw).expect("parses");
139        assert_eq!(repo.default_merge_style.as_deref(), Some("manually-merged"));
140    }
141
142    #[test]
143    fn an_absent_property_reads_as_none() {
144        let repo: Repository = facet_json::from_str("{}").expect("parses");
145        assert_eq!(repo.has_wiki, None);
146    }
147}