@@ -263,6 +263,31 @@ impl StringValue {
263263 pub fn as_str ( & self ) -> & str {
264264 self . 0 . as_str ( )
265265 }
266+
267+ /// Shortens this `StringValue` to the specified character length.
268+ pub fn truncate ( & mut self , new_len : usize ) {
269+ let s = self . as_ref ( ) ;
270+ if s. len ( ) > new_len {
271+ let new_value = truncate_str ( s, new_len) . to_string ( ) ;
272+
273+ match & self . 0 {
274+ OtelString :: Owned ( _) | OtelString :: Static ( _) => {
275+ self . 0 = OtelString :: Owned ( new_value. into_boxed_str ( ) ) ;
276+ }
277+ OtelString :: RefCounted ( _) => {
278+ self . 0 = OtelString :: RefCounted ( Arc :: from ( new_value. as_str ( ) ) )
279+ }
280+ }
281+ }
282+ }
283+ }
284+
285+ /// Returns a str truncated to the specified character length.
286+ fn truncate_str ( s : & str , new_len : usize ) -> & str {
287+ match s. char_indices ( ) . nth ( new_len) {
288+ None => s,
289+ Some ( ( idx, _) ) => & s[ ..idx] ,
290+ }
266291}
267292
268293impl From < StringValue > for String {
@@ -327,6 +352,17 @@ impl Value {
327352 Value :: Array ( v) => format ! ( "{v}" ) . into ( ) ,
328353 }
329354 }
355+
356+ /// Shortens this `Value` to the specified length.
357+ ///
358+ /// Only String and Array(String) values are truncated.
359+ pub fn truncate ( & mut self , new_len : usize ) {
360+ match self {
361+ Value :: Array ( Array :: String ( v) ) => v. iter_mut ( ) . for_each ( |s| s. truncate ( new_len) ) ,
362+ Value :: String ( s) => s. truncate ( new_len) ,
363+ _ => ( ) ,
364+ }
365+ }
330366}
331367
332368macro_rules! from_values {
@@ -628,7 +664,7 @@ impl InstrumentationScopeBuilder {
628664mod tests {
629665 use std:: hash:: { Hash , Hasher } ;
630666
631- use crate :: { InstrumentationScope , KeyValue } ;
667+ use crate :: { Array , InstrumentationScope , KeyValue , Value } ;
632668
633669 use rand:: random;
634670 use std:: collections:: hash_map:: DefaultHasher ;
@@ -695,6 +731,81 @@ mod tests {
695731 }
696732 }
697733
734+ #[ test]
735+ fn value_truncate ( ) {
736+ for test in [
737+ ( 0 , Value :: from ( true ) , Value :: from ( true ) ) ,
738+ (
739+ 0 ,
740+ Value :: Array ( Array :: Bool ( vec ! [ true , false ] ) ) ,
741+ Value :: Array ( Array :: Bool ( vec ! [ true , false ] ) ) ,
742+ ) ,
743+ ( 0 , Value :: from ( 42 ) , Value :: from ( 42 ) ) ,
744+ (
745+ 0 ,
746+ Value :: Array ( Array :: I64 ( vec ! [ 42 , -1 ] ) ) ,
747+ Value :: Array ( Array :: I64 ( vec ! [ 42 , -1 ] ) ) ,
748+ ) ,
749+ ( 0 , Value :: from ( 42.0 ) , Value :: from ( 42.0 ) ) ,
750+ (
751+ 0 ,
752+ Value :: Array ( Array :: F64 ( vec ! [ 42.0 , -1.0 ] ) ) ,
753+ Value :: Array ( Array :: F64 ( vec ! [ 42.0 , -1.0 ] ) ) ,
754+ ) ,
755+ ( 0 , Value :: from ( "value" ) , Value :: from ( "" ) ) ,
756+ (
757+ 0 ,
758+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
759+ Value :: Array ( Array :: String ( vec ! [ "" . into( ) , "" . into( ) ] ) ) ,
760+ ) ,
761+ ( 1 , Value :: from ( "value" ) , Value :: from ( "v" ) ) ,
762+ (
763+ 1 ,
764+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
765+ Value :: Array ( Array :: String ( vec ! [ "v" . into( ) , "v" . into( ) ] ) ) ,
766+ ) ,
767+ ( 5 , Value :: from ( "value" ) , Value :: from ( "value" ) ) ,
768+ (
769+ 7 ,
770+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
771+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
772+ ) ,
773+ (
774+ 6 ,
775+ Value :: Array ( Array :: String ( vec ! [ "value" . into( ) , "value-1" . into( ) ] ) ) ,
776+ Value :: Array ( Array :: String ( vec ! [ "value" . into( ) , "value-" . into( ) ] ) ) ,
777+ ) ,
778+ ( 128 , Value :: from ( "value" ) , Value :: from ( "value" ) ) ,
779+ (
780+ 128 ,
781+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
782+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
783+ ) ,
784+ ]
785+ . iter_mut ( )
786+ {
787+ test. 1 . truncate ( test. 0 ) ;
788+ assert_eq ! ( test. 1 , test. 2 )
789+ }
790+ }
791+
792+ #[ test]
793+ fn truncate_str ( ) {
794+ for test in [
795+ ( 5 , "" , "" ) ,
796+ ( 0 , "Zero" , "" ) ,
797+ ( 10 , "Short text" , "Short text" ) ,
798+ ( 1 , "Hello World!" , "H" ) ,
799+ ( 6 , "hello€€" , "hello€" ) ,
800+ ( 2 , "££££££" , "££" ) ,
801+ ( 8 , "hello€world" , "hello€wo" ) ,
802+ ]
803+ . iter ( )
804+ {
805+ assert_eq ! ( super :: truncate_str( test. 1 , test. 0 ) , test. 2 ) ;
806+ }
807+ }
808+
698809 fn hash_helper < T : Hash > ( item : & T ) -> u64 {
699810 let mut hasher = DefaultHasher :: new ( ) ;
700811 item. hash ( & mut hasher) ;
0 commit comments