Skip to main content

relay_knowledge/domain/operations/software/
request.rs

1use serde::{Deserialize, Serialize};
2
3use super::super::{CodeRepositorySelector, DomainError, FreshnessPolicy};
4
5/// Query kind for repository-scoped software global model facts.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum SoftwareGlobalKind {
9    Dependencies,
10    Sdks,
11    Files,
12    Topics,
13    Relationships,
14    Build,
15    Iac,
16    Design,
17    Systems,
18    Apis,
19    Resources,
20    Tests,
21    Deployments,
22    Releases,
23    Statements,
24    Conflicts,
25    All,
26}
27
28impl SoftwareGlobalKind {
29    /// Stable CLI, API, and storage-facing representation.
30    pub const fn as_str(self) -> &'static str {
31        match self {
32            Self::Dependencies => "dependencies",
33            Self::Sdks => "sdks",
34            Self::Files => "files",
35            Self::Topics => "topics",
36            Self::Relationships => "relationships",
37            Self::Build => "build",
38            Self::Iac => "iac",
39            Self::Design => "design",
40            Self::Systems => "systems",
41            Self::Apis => "apis",
42            Self::Resources => "resources",
43            Self::Tests => "tests",
44            Self::Deployments => "deployments",
45            Self::Releases => "releases",
46            Self::Statements => "statements",
47            Self::Conflicts => "conflicts",
48            Self::All => "all",
49        }
50    }
51}
52
53/// Repository-scoped software global model query.
54#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
55pub struct SoftwareGlobalRequest {
56    pub repository: CodeRepositorySelector,
57    pub kind: SoftwareGlobalKind,
58    pub freshness_policy: FreshnessPolicy,
59    pub limit: usize,
60}
61
62impl SoftwareGlobalRequest {
63    /// Validates the requested result bound while preserving repository scope.
64    pub fn new(
65        repository: CodeRepositorySelector,
66        kind: SoftwareGlobalKind,
67        freshness_policy: FreshnessPolicy,
68        limit: usize,
69    ) -> Result<Self, DomainError> {
70        let limit = match limit {
71            1..=500 => limit,
72            0 => return Err(DomainError::invalid("limit", "must be greater than zero")),
73            _ => return Err(DomainError::invalid("limit", "must be 500 or less")),
74        };
75
76        Ok(Self {
77            repository,
78            kind,
79            freshness_policy,
80            limit,
81        })
82    }
83}
84
85#[cfg(test)]
86#[path = "request_tests.rs"]
87mod tests;