@@ -1993,11 +1993,122 @@ pub fn parse_use_path(s: &str) -> anyhow::Result<ParsedUsePath> {
19931993 derive( serde_derive:: Serialize , serde_derive:: Deserialize )
19941994) ]
19951995#[ cfg_attr( feature = "serde" , serde( into = "String" , try_from = "String" ) ) ]
1996+ /// The fully-qualified name of a Component Model item (function,
1997+ /// type, or resource) as can be defined by wit. An item is optionally in a
1998+ /// package, the package optionally has a version, and the item is optionally
1999+ /// inside a namespace.
2000+ ///
2001+ /// The syntax for an ItemName always uses the package version as a suffix, if
2002+ /// it is given. The following tests show examples of the syntax for ItemName:
2003+ /// ```rust
2004+ /// # use wit_parser::{ItemName, PackageName};
2005+ /// assert_eq!(
2006+ /// "foo".parse::<ItemName>().unwrap(),
2007+ /// ItemName {
2008+ /// package: None,
2009+ /// interface: None,
2010+ /// name: "foo".to_owned()
2011+ /// }
2012+ /// );
2013+ /// assert_eq!(
2014+ /// "foo.bar".parse::<ItemName>().unwrap(),
2015+ /// ItemName {
2016+ /// package: None,
2017+ /// interface: Some("foo".to_owned()),
2018+ /// name: "bar".to_owned()
2019+ /// }
2020+ /// );
2021+ /// assert_eq!(
2022+ /// "foo:bar/baz".parse::<ItemName>().unwrap(),
2023+ /// ItemName {
2024+ /// package: Some(PackageName {
2025+ /// namespace: "foo".to_owned(),
2026+ /// name: "bar".to_owned(),
2027+ /// version: None
2028+ /// }),
2029+ /// interface: None,
2030+ /// name: "baz".to_owned()
2031+ /// }
2032+ /// );
2033+ /// assert_eq!(
2034+ /// "foo:bar/baz@0.1.0".parse::<ItemName>().unwrap(),
2035+ /// ItemName {
2036+ /// package: Some(PackageName {
2037+ /// namespace: "foo".to_owned(),
2038+ /// name: "bar".to_owned(),
2039+ /// version: Some("0.1.0".parse().unwrap())
2040+ /// }),
2041+ /// interface: None,
2042+ /// name: "baz".to_owned()
2043+ /// }
2044+ /// );
2045+ /// assert_eq!(
2046+ /// "foo:bar/baz.bat".parse::<ItemName>().unwrap(),
2047+ /// ItemName {
2048+ /// package: Some(PackageName {
2049+ /// namespace: "foo".to_owned(),
2050+ /// name: "bar".to_owned(),
2051+ /// version: None
2052+ /// }),
2053+ /// interface: Some("baz".to_owned()),
2054+ /// name: "bat".to_owned()
2055+ /// }
2056+ /// );
2057+ /// assert_eq!(
2058+ /// "foo:bar/baz.bat@0.1.0".parse::<ItemName>().unwrap(),
2059+ /// ItemName {
2060+ /// package: Some(PackageName {
2061+ /// namespace: "foo".to_owned(),
2062+ /// name: "bar".to_owned(),
2063+ /// version: Some("0.1.0".parse().unwrap()),
2064+ /// }),
2065+ /// interface: Some("baz".to_owned()),
2066+ /// name: "bat".to_owned()
2067+ /// }
2068+ /// );
2069+ /// assert!("foo@0.1.0".parse::<ItemName>().is_err());
2070+ /// assert!("foo:bar@0.1.0".parse::<ItemName>().is_err());
2071+ /// assert!("foo:bar/baz@0.1.0.bat".parse::<ItemName>().is_err());
2072+ /// assert!("foo.bar@0.1.0".parse::<ItemName>().is_err());
2073+ /// assert!("foo@0.1.0.bar".parse::<ItemName>().is_err());
2074+ /// ```
2075+ ///
2076+ /// Parse this from a string using its [`FromStr`](core::str::FromStr) or
2077+ /// [`TryFrom<String>`](core::convert::TryFrom) impls.
2078+ /// [`Display`](core::fmt::Display) to render to the same string syntax.
19962079pub struct ItemName {
19972080 pub package : Option < crate :: PackageName > ,
19982081 pub interface : Option < String > ,
19992082 pub name : String ,
20002083}
2084+ impl ItemName {
2085+ /// Get the name of the component instance containing this item, if any.
2086+ /// The instance name will be formed like:
2087+ /// "namespace.packagename/interfacename@0.1.0"
2088+ pub fn instance_name ( & self ) -> Option < String > {
2089+ if self . package . is_none ( ) && self . interface . is_none ( ) {
2090+ return None ;
2091+ }
2092+ let mut s = String :: new ( ) ;
2093+ if let Some ( crate :: PackageName {
2094+ namespace, name, ..
2095+ } ) = & self . package
2096+ {
2097+ s. push_str ( & format ! ( "{namespace}:{name}/" ) ) ;
2098+ }
2099+ if let Some ( name) = & self . interface {
2100+ s. push_str ( & format ! ( "{name}" ) ) ;
2101+ }
2102+ if let Some ( crate :: PackageName {
2103+ version : Some ( version) ,
2104+ ..
2105+ } ) = & self . package
2106+ {
2107+ s. push_str ( & format ! ( "@{version}" ) ) ;
2108+ }
2109+ Some ( s)
2110+ }
2111+ }
20012112impl core:: str:: FromStr for ItemName {
20022113 type Err = anyhow:: Error ;
20032114 fn from_str ( s : & str ) -> anyhow:: Result < ItemName > {
0 commit comments