Codex Handbook
protocol/src/tool_name.rs 76 lines
use serde::Deserialize;use serde::Serialize;use std::cmp::Ordering;use std::fmt;/// Identifies a callable tool, preserving the namespace split when the model/// provides one.#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]pub struct ToolName {    pub name: String,    pub namespace: Option<String>,}impl ToolName {    pub fn new(namespace: Option<String>, name: impl Into<String>) -> Self {        Self {            name: name.into(),            namespace,        }    }    pub fn plain(name: impl Into<String>) -> Self {        Self {            name: name.into(),            namespace: None,        }    }    pub fn namespaced(namespace: impl Into<String>, name: impl Into<String>) -> Self {        Self {            name: name.into(),            namespace: Some(namespace.into()),        }    }}impl fmt::Display for ToolName {    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {        match &self.namespace {            Some(namespace) => write!(f, "{namespace}{}", self.name),            None => f.write_str(&self.name),        }    }}impl Ord for ToolName {    fn cmp(&self, other: &Self) -> Ordering {        let lhs = match &self.namespace {            Some(namespace) => (namespace.as_str(), Some(self.name.as_str())),            None => (self.name.as_str(), None),        };        let rhs = match &other.namespace {            Some(namespace) => (namespace.as_str(), Some(other.name.as_str())),            None => (other.name.as_str(), None),        };        lhs.cmp(&rhs)    }}impl PartialOrd for ToolName {    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {        Some(self.cmp(other))    }}impl From<String> for ToolName {    fn from(name: String) -> Self {        Self::plain(name)    }}impl From<&str> for ToolName {    fn from(name: &str) -> Self {        Self::plain(name)    }}