Skip to main content

switchyard_protocol/
category.rs

1// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Category is a group of models
5
6use std::str::FromStr;
7use std::sync::Arc;
8
9/// A group of models
10#[derive(Clone, Debug, PartialEq, Eq, Hash)]
11pub enum Category {
12    /// When the category doesn't matter: Random, Passthrough, etc.
13    Any,
14    /// High accuracy and cost models.
15    Capable,
16    /// Lower accuracy and cost models.
17    Efficient,
18    /// Models the algorithm can use to decide.
19    Judge,
20    /// A deployment-defined group. Only a custom classifier's policy selects one,
21    /// and no algorithm ascribes meaning to the name.
22    Named(Arc<str>),
23}
24
25impl Category {
26    /// Returns the lowercase category name used in configuration.
27    pub fn as_str(&self) -> &str {
28        match self {
29            Self::Any => "any",
30            Self::Capable => "capable",
31            Self::Efficient => "efficient",
32            Self::Judge => "judge",
33            Self::Named(name) => name,
34        }
35    }
36}
37
38impl FromStr for Category {
39    type Err = String;
40
41    /// The four reserved names are matched first. Were `"capable"` allowed to
42    /// become a [`Category::Named`] there would be two keys that compare unequal
43    /// but print the same, and a lookup of [`Category::Capable`] would silently
44    /// miss the configured group.
45    fn from_str(s: &str) -> Result<Self, Self::Err> {
46        let c = match s {
47            "capable" => Self::Capable,
48            "efficient" => Self::Efficient,
49            "judge" => Self::Judge,
50            "any" => Self::Any,
51            "" => return Err("Category name cannot be empty".to_string()),
52            name => Self::Named(Arc::from(name)),
53        };
54        Ok(c)
55    }
56}