@@ -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,20 @@ 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 ( ref mut a) => match a {
362+ Array :: String ( ref mut v) => v. iter_mut ( ) . for_each ( |s| s. truncate ( new_len) ) ,
363+ _ => ( ) ,
364+ } ,
365+ Value :: String ( s) => s. truncate ( new_len) ,
366+ _ => ( ) ,
367+ }
368+ }
330369}
331370
332371macro_rules! from_values {
@@ -628,7 +667,7 @@ impl InstrumentationScopeBuilder {
628667mod tests {
629668 use std:: hash:: { Hash , Hasher } ;
630669
631- use crate :: { InstrumentationScope , KeyValue } ;
670+ use crate :: { Array , InstrumentationScope , KeyValue , Value } ;
632671
633672 use rand:: random;
634673 use std:: collections:: hash_map:: DefaultHasher ;
@@ -695,6 +734,81 @@ mod tests {
695734 }
696735 }
697736
737+ #[ test]
738+ fn value_truncate ( ) {
739+ for test in [
740+ ( 0 , Value :: from ( true ) , Value :: from ( true ) ) ,
741+ (
742+ 0 ,
743+ Value :: Array ( Array :: Bool ( vec ! [ true , false ] ) ) ,
744+ Value :: Array ( Array :: Bool ( vec ! [ true , false ] ) ) ,
745+ ) ,
746+ ( 0 , Value :: from ( 42 ) , Value :: from ( 42 ) ) ,
747+ (
748+ 0 ,
749+ Value :: Array ( Array :: I64 ( vec ! [ 42 , -1 ] ) ) ,
750+ Value :: Array ( Array :: I64 ( vec ! [ 42 , -1 ] ) ) ,
751+ ) ,
752+ ( 0 , Value :: from ( 42.0 ) , Value :: from ( 42.0 ) ) ,
753+ (
754+ 0 ,
755+ Value :: Array ( Array :: F64 ( vec ! [ 42.0 , -1.0 ] ) ) ,
756+ Value :: Array ( Array :: F64 ( vec ! [ 42.0 , -1.0 ] ) ) ,
757+ ) ,
758+ ( 0 , Value :: from ( "value" ) , Value :: from ( "" ) ) ,
759+ (
760+ 0 ,
761+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
762+ Value :: Array ( Array :: String ( vec ! [ "" . into( ) , "" . into( ) ] ) ) ,
763+ ) ,
764+ ( 1 , Value :: from ( "value" ) , Value :: from ( "v" ) ) ,
765+ (
766+ 1 ,
767+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
768+ Value :: Array ( Array :: String ( vec ! [ "v" . into( ) , "v" . into( ) ] ) ) ,
769+ ) ,
770+ ( 5 , Value :: from ( "value" ) , Value :: from ( "value" ) ) ,
771+ (
772+ 7 ,
773+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
774+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
775+ ) ,
776+ (
777+ 6 ,
778+ Value :: Array ( Array :: String ( vec ! [ "value" . into( ) , "value-1" . into( ) ] ) ) ,
779+ Value :: Array ( Array :: String ( vec ! [ "value" . into( ) , "value-" . into( ) ] ) ) ,
780+ ) ,
781+ ( 128 , Value :: from ( "value" ) , Value :: from ( "value" ) ) ,
782+ (
783+ 128 ,
784+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
785+ Value :: Array ( Array :: String ( vec ! [ "value-0" . into( ) , "value-1" . into( ) ] ) ) ,
786+ ) ,
787+ ]
788+ . iter_mut ( )
789+ {
790+ test. 1 . truncate ( test. 0 ) ;
791+ assert_eq ! ( test. 1 , test. 2 )
792+ }
793+ }
794+
795+ #[ test]
796+ fn truncate_str ( ) {
797+ for test in [
798+ ( 5 , "" , "" ) ,
799+ ( 0 , "Zero" , "" ) ,
800+ ( 10 , "Short text" , "Short text" ) ,
801+ ( 1 , "Hello World!" , "H" ) ,
802+ ( 6 , "hello€€" , "hello€" ) ,
803+ ( 2 , "££££££" , "££" ) ,
804+ ( 8 , "hello€world" , "hello€wo" ) ,
805+ ]
806+ . iter ( )
807+ {
808+ assert_eq ! ( super :: truncate_str( test. 1 , test. 0 ) , test. 2 ) ;
809+ }
810+ }
811+
698812 fn hash_helper < T : Hash > ( item : & T ) -> u64 {
699813 let mut hasher = DefaultHasher :: new ( ) ;
700814 item. hash ( & mut hasher) ;
0 commit comments