@@ -58,6 +58,16 @@ pub enum KeyError {
5858/// [k8s-labels]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
5959#[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
6060pub struct Key {
61+ /// A cached and formatted representation of a [`Key`] as a [`String`], which enables the
62+ /// implementation of [`Deref`], instead of constructing a new [`String`] every time the string
63+ /// representation of a key is needed.
64+ ///
65+ /// ### Safety
66+ ///
67+ /// This is safe to do (and cache it), because [`Key`] doesn't provide any **mutable** access
68+ /// to the inner values.
69+ string : String ,
70+
6171 prefix : Option < KeyPrefix > ,
6272 name : KeyName ,
6373}
@@ -80,12 +90,22 @@ impl FromStr for Key {
8090 _ => return NestedPrefixSnafu . fail ( ) ,
8191 } ;
8292
93+ let prefix = prefix
94+ . map ( KeyPrefix :: from_str)
95+ . transpose ( )
96+ . context ( KeyPrefixSnafu ) ?;
97+
98+ let name = KeyName :: from_str ( name) . context ( KeyNameSnafu ) ?;
99+
100+ let string = match prefix {
101+ Some ( ref prefix) => format ! ( "{prefix}/{name}" ) ,
102+ None => format ! ( "{name}" ) ,
103+ } ;
104+
83105 let key = Self {
84- prefix : prefix
85- . map ( KeyPrefix :: from_str)
86- . transpose ( )
87- . context ( KeyPrefixSnafu ) ?,
88- name : KeyName :: from_str ( name) . context ( KeyNameSnafu ) ?,
106+ string,
107+ prefix,
108+ name,
89109 } ;
90110
91111 Ok ( key)
@@ -102,10 +122,15 @@ impl TryFrom<&str> for Key {
102122
103123impl Display for Key {
104124 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
105- match & self . prefix {
106- Some ( prefix) => write ! ( f, "{}/{}" , prefix, self . name) ,
107- None => write ! ( f, "{}" , self . name) ,
108- }
125+ write ! ( f, "{key}" , key = self . string)
126+ }
127+ }
128+
129+ impl Deref for Key {
130+ type Target = str ;
131+
132+ fn deref ( & self ) -> & Self :: Target {
133+ self . string . as_str ( )
109134 }
110135}
111136
0 commit comments