relay_knowledge/domain/business/
query.rs1use serde::{Deserialize, Serialize};
2
3use crate::domain::{CodeRepositorySelector, DomainError, FreshnessPolicy};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum BusinessKnowledgeQueryKind {
9 Terms,
10 Mappings,
11 All,
12}
13
14impl BusinessKnowledgeQueryKind {
15 pub const fn as_str(self) -> &'static str {
16 match self {
17 Self::Terms => "terms",
18 Self::Mappings => "mappings",
19 Self::All => "all",
20 }
21 }
22}
23
24#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
26pub struct BusinessKnowledgeQueryRequest {
27 pub repository: CodeRepositorySelector,
28 #[serde(default, skip_serializing_if = "Option::is_none")]
29 pub domain: Option<String>,
30 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub query: Option<String>,
32 pub kind: BusinessKnowledgeQueryKind,
33 pub freshness_policy: FreshnessPolicy,
34 pub limit: usize,
35}
36
37impl BusinessKnowledgeQueryRequest {
38 pub fn new(
39 repository: CodeRepositorySelector,
40 domain: Option<String>,
41 query: Option<String>,
42 kind: BusinessKnowledgeQueryKind,
43 freshness_policy: FreshnessPolicy,
44 limit: usize,
45 ) -> Result<Self, DomainError> {
46 if !(1..=500).contains(&limit) {
47 return Err(DomainError::invalid("limit", "must be between 1 and 500"));
48 }
49 let domain = validate_optional("domain", domain, 128)?;
50 let query = validate_optional("query", query, 1_024)?;
51 Ok(Self {
52 repository,
53 domain,
54 query,
55 kind,
56 freshness_policy,
57 limit,
58 })
59 }
60}
61
62fn validate_optional(
63 field: &'static str,
64 value: Option<String>,
65 max_bytes: usize,
66) -> Result<Option<String>, DomainError> {
67 value
68 .map(|value| {
69 let value = value.trim();
70 if value.is_empty() {
71 return Err(DomainError::invalid(field, "must not be empty"));
72 }
73 if value.len() > max_bytes {
74 return Err(DomainError::invalid(
75 field,
76 format!("must be {max_bytes} bytes or less"),
77 ));
78 }
79 Ok(value.to_owned())
80 })
81 .transpose()
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
86#[serde(rename_all = "snake_case")]
87pub enum BusinessKnowledgeResolution {
88 List,
89 Exact,
90 Ambiguous,
91 NotFound,
92}
93
94#[cfg(test)]
95#[path = "query_tests.rs"]
96mod tests;