use std::fmt;
edgefirst_tensor::ef_vocabulary! {
#[non_exhaustive]
pub enum ConfigSource {
EmbeddedEdgefirst = 0, "embedded_edgefirst", EMBEDDED_EDGEFIRST,
SidecarEdgefirst = 1, "sidecar_edgefirst", SIDECAR_EDGEFIRST,
EmbeddedHf = 2, "embedded_hf", EMBEDDED_HF,
SidecarHf = 3, "sidecar_hf", SIDECAR_HF,
UltralyticsMetadata = 4, "ultralytics_metadata", ULTRALYTICS_METADATA,
Heuristic = 5, "heuristic", HEURISTIC,
Default = 6, "default", DEFAULT,
Override = 7, "override", OVERRIDE,
}
#[doc(hidden)]
pub mod config_source_code;
}
edgefirst_tensor::ef_vocabulary! {
#[non_exhaustive]
pub enum ModelFamily {
EdgeFirst = 0, "edgefirst", EDGEFIRST,
Ultralytics = 1, "ultralytics", ULTRALYTICS,
HuggingFace = 2, "huggingface", HUGGINGFACE,
Unknown = 3, "unknown", UNKNOWN,
}
#[doc(hidden)]
pub mod model_family_code;
}
edgefirst_tensor::ef_vocabulary! {
#[non_exhaustive]
pub enum ModelTask {
Detect = 0, "detect", DETECT,
Segment = 1, "segment", SEGMENT,
Semantic = 2, "semantic", SEMANTIC,
}
#[doc(hidden)]
pub mod model_task_code;
}
edgefirst_tensor::ef_vocabulary! {
#[derive(PartialOrd, Ord)]
#[non_exhaustive]
pub enum ConfigField {
Normalization = 0, "normalize", NORMALIZATION,
Resize = 1, "resize", RESIZE,
Placement = 2, "placement", PLACEMENT,
Pad = 3, "pad", PAD,
Interpolation = 4, "interpolation", INTERPOLATION,
Task = 5, "task", TASK,
DecodeMode = 6, "decode", DECODE_MODE,
Labels = 7, "labels", LABELS,
Size = 8, "size", SIZE,
}
#[doc(hidden)]
pub mod config_field_code;
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct Provenance {
pub source: ConfigSource,
pub detail: Option<String>,
}
impl Provenance {
pub fn new(source: ConfigSource, detail: Option<&str>) -> Self {
Self {
source,
detail: detail.map(str::to_owned),
}
}
}
impl fmt::Display for Provenance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let detail = self.detail.as_deref();
match (self.source, detail) {
(ConfigSource::Heuristic, Some(d)) => write!(f, "guess: {d}"),
(ConfigSource::Heuristic, None) => f.write_str("guess"),
(ConfigSource::Default, Some(d)) => write!(f, "default: {d}"),
(ConfigSource::Default, None) => f.write_str("default"),
(ConfigSource::Override, _) => f.write_str("override"),
(ConfigSource::UltralyticsMetadata, _) => f.write_str("ultralytics metadata"),
(_, Some(d)) => f.write_str(d),
(ConfigSource::EmbeddedEdgefirst, None) => f.write_str("edgefirst.json"),
(ConfigSource::SidecarEdgefirst, None) => f.write_str("sidecar edgefirst.json"),
(ConfigSource::EmbeddedHf, None) => f.write_str("embedded hugging face config"),
(ConfigSource::SidecarHf, None) => f.write_str("sidecar hugging face config"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vocabularies_round_trip_codes_and_strings() {
for &s in ConfigSource::all() {
assert_eq!(ConfigSource::from_code(s.code()), Some(s));
assert_eq!(ConfigSource::from_str_code(s.as_str()), Some(s));
}
for &m in ModelFamily::all() {
assert_eq!(ModelFamily::from_str_code(m.as_str()), Some(m));
}
for &t in ModelTask::all() {
assert_eq!(ModelTask::from_str_code(t.as_str()), Some(t));
}
for (i, &c) in ConfigField::all().iter().enumerate() {
assert_eq!(c.code() as usize, i, "fields describe in code order");
assert_eq!(ConfigField::from_str_code(c.as_str()), Some(c));
}
}
#[test]
fn provenance_displays_bracket_text() {
let p = |s, d| Provenance::new(s, d).to_string();
assert_eq!(
p(ConfigSource::SidecarHf, Some("preprocessor_config.json")),
"preprocessor_config.json"
);
assert_eq!(
p(ConfigSource::Heuristic, Some("SegFormer default")),
"guess: SegFormer default"
);
assert_eq!(p(ConfigSource::Override, None), "override");
assert_eq!(p(ConfigSource::Default, None), "default");
assert_eq!(p(ConfigSource::EmbeddedEdgefirst, None), "edgefirst.json");
assert_eq!(
p(ConfigSource::UltralyticsMetadata, None),
"ultralytics metadata"
);
}
}