@@ -79,13 +79,13 @@ where
7979 pub fn with < L , K , V > ( & self , dynamic_labels : L ) -> Counter < T >
8080 where
8181 L : IntoIterator < Item = ( K , V ) > ,
82- K : AsRef < str > ,
83- V : AsRef < str > ,
82+ K : Into < String > ,
83+ V : Into < String > ,
8484 {
8585 // Convert dynamic_labels to HashMap first
8686 let dynamic_labels_map: HashMap < String , String > = dynamic_labels
8787 . into_iter ( )
88- . map ( |( k, v) | ( k. as_ref ( ) . to_string ( ) , v. as_ref ( ) . to_string ( ) ) )
88+ . map ( |( k, v) | ( k. into ( ) , v. into ( ) ) )
8989 . collect ( ) ;
9090
9191 // Validate required keys are present
@@ -138,3 +138,77 @@ where
138138 )
139139 }
140140}
141+
142+ /// Builder for creating counter schemas with static labels and required dynamic keys
143+ pub struct CounterSchemaBuilder < T > {
144+ name : String ,
145+ static_labels : Vec < ( String , String ) > ,
146+ required_dynamic_keys : HashSet < String > ,
147+ registry : Arc < metrics:: Registry > ,
148+ _phantom : std:: marker:: PhantomData < T > ,
149+ }
150+
151+ impl < T > CounterSchemaBuilder < T >
152+ where
153+ Arc < AtomicU64 > : CounterOps < T > ,
154+ T : One + Send + Sync + ' static ,
155+ {
156+ pub ( crate ) fn new ( name : String , registry : Arc < metrics:: Registry > ) -> Self {
157+ Self {
158+ name,
159+ static_labels : Vec :: new ( ) ,
160+ required_dynamic_keys : HashSet :: new ( ) ,
161+ registry,
162+ _phantom : std:: marker:: PhantomData ,
163+ }
164+ }
165+
166+ /// Add static labels that are set once when the schema is created
167+ pub fn static_labels < I , K , V > ( mut self , labels : I ) -> Self
168+ where
169+ I : IntoIterator < Item = ( K , V ) > ,
170+ K : AsRef < str > ,
171+ V : AsRef < str > ,
172+ {
173+ for ( key, value) in labels {
174+ self . static_labels
175+ . push ( ( key. as_ref ( ) . to_string ( ) , value. as_ref ( ) . to_string ( ) ) ) ;
176+ }
177+ self
178+ }
179+
180+ /// Add a single static label
181+ pub fn static_label ( mut self , key : & str , value : & str ) -> Self {
182+ self . static_labels
183+ . push ( ( key. to_string ( ) , value. to_string ( ) ) ) ;
184+ self
185+ }
186+
187+ /// Specify required dynamic label keys that must be provided at increment time
188+ pub fn require_dynamic_keys < I , K > ( mut self , keys : I ) -> Self
189+ where
190+ I : IntoIterator < Item = K > ,
191+ K : AsRef < str > ,
192+ {
193+ for key in keys {
194+ self . required_dynamic_keys . insert ( key. as_ref ( ) . to_string ( ) ) ;
195+ }
196+ self
197+ }
198+
199+ /// Add a single required dynamic key
200+ pub fn require_dynamic_key ( mut self , key : & str ) -> Self {
201+ self . required_dynamic_keys . insert ( key. to_string ( ) ) ;
202+ self
203+ }
204+
205+ /// Build the counter schema
206+ pub fn build ( self ) -> Schema < T > {
207+ Schema :: new (
208+ self . name ,
209+ self . static_labels ,
210+ self . required_dynamic_keys ,
211+ self . registry ,
212+ )
213+ }
214+ }
0 commit comments