obz_core/provider/params.rs
1//! Query parameter types passed to provider trait methods.
2//!
3//! These structs carry the parsed CLI arguments to the provider
4//! implementation. They are backend-agnostic — the same parameter
5//! types are used across all providers.
6//!
7//! Provider-specific configuration (e.g., project names, tenant IDs)
8//! is passed at provider construction time, not per-query.
9
10use std::time::Duration;
11
12use crate::model::error::{ErrorCode, ObzError};
13
14/// Query parameters for `metric query` (instant or range).
15#[derive(Debug, Clone)]
16pub struct MetricQueryParams {
17 /// Query expression (`PromQL`, `MetricsQL`, DQL).
18 pub query: String,
19 /// Whether the user explicitly requested a range query.
20 ///
21 /// Set by the shell layer based on the presence of `--from`, `--to`,
22 /// or `--step` flags.
23 pub is_range: bool,
24 /// Start time as Unix seconds.
25 pub start: i64,
26 /// End time as Unix seconds.
27 pub end: i64,
28 /// Query step interval in seconds (range queries only).
29 pub step: Option<u64>,
30 /// Maximum number of series to return.
31 pub limit: Option<usize>,
32 /// Query timeout.
33 pub timeout: Option<Duration>,
34}
35
36impl MetricQueryParams {
37 /// Default target number of data points when `--step` is omitted.
38 pub const DEFAULT_TARGET_POINTS: i64 = 100;
39
40 /// Return the step in seconds, falling back to an auto-calculated value
41 /// that targets approximately [`Self::DEFAULT_TARGET_POINTS`] data points.
42 pub fn step_or_auto(&self) -> u64 {
43 self.step.unwrap_or_else(|| {
44 let duration = (self.end - self.start).max(0);
45 std::cmp::max(1, (duration / Self::DEFAULT_TARGET_POINTS) as u64)
46 })
47 }
48}
49
50/// Parameters for `metric list`, `labels`, `series`.
51#[derive(Debug, Clone)]
52pub struct MetricMetadataParams {
53 /// Match expression (series selector or prefix filter).
54 pub match_expr: Option<String>,
55 /// Additional match expressions (for `series` command).
56 pub match_exprs: Vec<String>,
57 /// Start time as Unix seconds.
58 pub start: Option<i64>,
59 /// End time as Unix seconds.
60 pub end: Option<i64>,
61 /// Maximum number of results to return.
62 pub limit: Option<usize>,
63}
64
65/// Parameters for `metric info`.
66#[derive(Debug, Clone)]
67pub struct MetricInfoParams {
68 /// Metric name to look up.
69 pub metric_name: String,
70}
71
72/// Parameters for `metric label-values`.
73#[derive(Debug, Clone)]
74pub struct LabelValuesParams {
75 /// Label name to get values for.
76 pub label_name: String,
77 /// Match expression (series selector filter).
78 pub match_expr: Option<String>,
79 /// Start time as Unix seconds.
80 pub start: Option<i64>,
81 /// End time as Unix seconds.
82 pub end: Option<i64>,
83 /// Maximum number of results to return.
84 pub limit: Option<usize>,
85}
86
87/// Query parameters for `log search`.
88#[derive(Debug, Clone)]
89pub struct LogSearchParams {
90 /// Query expression.
91 pub query: String,
92 /// Start time as Unix seconds.
93 pub start: i64,
94 /// End time as Unix seconds.
95 pub end: i64,
96 /// Maximum number of entries to return.
97 pub limit: usize,
98}
99
100/// Query parameters for `trace search`.
101#[derive(Debug, Clone)]
102pub struct TraceSearchParams {
103 /// Query expression.
104 pub query: String,
105 /// Start time as Unix seconds.
106 pub start: i64,
107 /// End time as Unix seconds.
108 pub end: i64,
109 /// Maximum number of spans to return.
110 pub limit: usize,
111}
112
113/// Parameters for `trace get`.
114#[derive(Debug, Clone)]
115pub struct TraceGetParams {
116 /// Trace ID (hex format).
117 pub trace_id: String,
118 /// Start time as Unix seconds.
119 pub start: i64,
120 /// End time as Unix seconds.
121 pub end: i64,
122}
123
124/// Parameters for extension commands.
125///
126/// Extension commands receive a dynamic list of key-value arguments
127/// parsed from CLI flags declared in [`CommandDescriptor`](crate::descriptor::CommandDescriptor).
128/// Repeatable flags produce multiple entries with the same key.
129#[derive(Debug, Clone)]
130pub struct ExtensionParams {
131 /// Start time as Unix seconds (if applicable).
132 pub start: Option<i64>,
133 /// End time as Unix seconds (if applicable).
134 pub end: Option<i64>,
135 /// The signal group this extension command belongs to.
136 pub signal: String,
137 /// Dynamic key-value arguments from extension command flags.
138 pub args: Vec<(String, String)>,
139}
140
141impl ExtensionParams {
142 /// Get an optional single-value argument by name.
143 pub fn get(&self, name: &str) -> Option<&str> {
144 self.args
145 .iter()
146 .find(|(k, _)| k == name)
147 .map(|(_, v)| v.as_str())
148 }
149
150 /// Get a required single-value argument by name.
151 ///
152 /// # Errors
153 ///
154 /// Returns [`ObzError::InvalidArgument`] when the argument is missing.
155 pub fn require(&self, name: &str) -> Result<&str, ObzError> {
156 self.get(name).ok_or_else(|| ObzError::InvalidArgument {
157 code: ErrorCode::MissingRequired,
158 message: format!("missing required argument: --{name}"),
159 suggestion: None,
160 })
161 }
162
163 /// Get all values for a repeatable argument (same key may appear multiple times).
164 pub fn get_all(&self, name: &str) -> Vec<&str> {
165 self.args
166 .iter()
167 .filter(|(k, _)| k == name)
168 .map(|(_, v)| v.as_str())
169 .collect()
170 }
171}