Skip to main content

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}