1use objects::object::ChangeId;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ListRefs {
7 #[serde(default)]
8 pub repo_path: Option<String>,
9 #[serde(default)]
10 pub filter: Option<RefFilter>,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct RefFilter {
15 #[serde(default)]
16 pub names: Vec<String>,
17 #[serde(default)]
18 pub patterns: Vec<String>,
19 #[serde(default = "default_true")]
20 pub include_threads: bool,
21 #[serde(default = "default_true")]
22 pub include_markers: bool,
23 #[serde(default)]
24 pub limit: Option<usize>,
25}
26
27fn default_true() -> bool {
28 true
29}
30
31impl Default for RefFilter {
32 fn default() -> Self {
33 Self {
34 names: Vec::new(),
35 patterns: Vec::new(),
36 include_threads: true,
37 include_markers: true,
38 limit: None,
39 }
40 }
41}
42
43impl RefFilter {
44 pub fn matches(&self, name: &str) -> bool {
45 if !self.names.is_empty() && self.names.iter().any(|candidate| candidate == name) {
46 return true;
47 }
48
49 if self.patterns.is_empty() {
50 return self.names.is_empty();
51 }
52
53 self.patterns
54 .iter()
55 .any(|pattern| Self::matches_pattern(name, pattern))
56 }
57
58 fn matches_pattern(name: &str, pattern: &str) -> bool {
59 if pattern == "*" {
60 return true;
61 }
62 if pattern.starts_with('*') && pattern.ends_with('*') && pattern.len() >= 2 {
63 return name.contains(&pattern[1..pattern.len() - 1]);
64 }
65 if let Some(suffix) = pattern.strip_prefix('*') {
66 return name.ends_with(suffix);
67 }
68 if let Some(prefix) = pattern.strip_suffix('*') {
69 return name.starts_with(prefix);
70 }
71 name == pattern
72 }
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub enum HeadInfo {
77 Attached { thread: String },
78 Detached { state: ChangeId },
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct RefsList {
83 pub head: HeadInfo,
84 pub head_state: Option<ChangeId>,
85 pub refs: Vec<RefEntry>,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct RefEntry {
90 pub name: String,
91 pub change_id: ChangeId,
92 pub is_thread: bool,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct UpdateRef {
97 pub name: String,
98 #[serde(default)]
99 pub is_thread: bool,
100 pub old_value: Option<ChangeId>,
101 pub new_value: ChangeId,
102 pub force: bool,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct RefUpdated {
107 pub success: bool,
108 pub old_value: Option<ChangeId>,
109 pub error: Option<String>,
110}