use crate::runtime_manifest::RuntimeManifestError;
pub const TRACE_CAPTURE_ACCEPTED_VALUES: &[&str] = &["none", "meta", "content"];
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum TraceCapture {
None,
#[default]
Meta,
Content,
}
impl TraceCapture {
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
Self::None => "none",
Self::Meta => "meta",
Self::Content => "content",
}
}
#[must_use]
pub fn captures_content(self) -> bool {
matches!(self, Self::Content)
}
#[must_use]
pub fn captures_hashes(self) -> bool {
!matches!(self, Self::None)
}
}
impl std::str::FromStr for TraceCapture {
type Err = ParseTraceCaptureError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value.trim() {
"none" => Ok(Self::None),
"meta" => Ok(Self::Meta),
"content" => Ok(Self::Content),
other => Err(ParseTraceCaptureError {
value: other.to_string(),
}),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseTraceCaptureError {
pub value: String,
}
impl std::fmt::Display for ParseTraceCaptureError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"must be one of: {}; got '{}'",
TRACE_CAPTURE_ACCEPTED_VALUES.join(", "),
self.value
)
}
}
impl std::error::Error for ParseTraceCaptureError {}
pub fn resolve_trace_capture(capture: Option<&str>) -> Result<TraceCapture, RuntimeManifestError> {
let Some(value) = capture else {
return Ok(TraceCapture::default());
};
value.parse().map_err(
|e: ParseTraceCaptureError| RuntimeManifestError::InvalidTraceConfig {
field: "trace.capture".to_string(),
message: e.to_string(),
},
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn absent_keys_resolve_to_meta() {
assert_eq!(resolve_trace_capture(None).unwrap(), TraceCapture::Meta);
assert_eq!(TraceCapture::default(), TraceCapture::Meta);
}
#[test]
fn each_capture_name_parses() {
assert_eq!(
resolve_trace_capture(Some("none")).unwrap(),
TraceCapture::None
);
assert_eq!(
resolve_trace_capture(Some("meta")).unwrap(),
TraceCapture::Meta
);
assert_eq!(
resolve_trace_capture(Some("content")).unwrap(),
TraceCapture::Content
);
}
#[test]
fn unknown_capture_value_names_the_field_and_the_accepted_values() {
let err = resolve_trace_capture(Some("verbose")).unwrap_err();
let rendered = err.to_string();
assert!(rendered.contains("trace.capture"), "{rendered}");
for accepted in TRACE_CAPTURE_ACCEPTED_VALUES {
assert!(rendered.contains(accepted), "{rendered}");
}
assert!(rendered.contains("verbose"), "{rendered}");
}
}