1- use crate :: transform:: Footprint ;
21use std:: any:: TypeId ;
32pub use std:: borrow:: Cow ;
43use std:: fmt:: { Display , Formatter } ;
@@ -346,8 +345,73 @@ pub fn simplify_identifier_name(ty: &str) -> String {
346345 . join ( "<" )
347346}
348347
348+ /// Converts a Rust-internal type name to its user-facing form.
349349pub fn make_type_user_readable ( ty : & str ) -> String {
350- ty. replace ( "Option<Arc<OwnedContextImpl>>" , "Context" ) . replace ( "Raster<CPU>" , "Raster" ) . replace ( "Raster<GPU>" , "Raster" )
350+ let ty = ty
351+ . replace ( "Option<Arc<OwnedContextImpl>>" , "Context" )
352+ . replace ( "Raster<CPU>" , "Raster" )
353+ . replace ( "Raster<GPU>" , "Raster" )
354+ . replace ( "DAffine2" , "Transform" )
355+ . replace ( "Affine2" , "Transform" )
356+ . replace ( "DVec2" , "Vec2" )
357+ . replace ( "IVec2" , "Vec2" )
358+ . replace ( "UVec2" , "Vec2" )
359+ . replace ( "&str" , "String" ) ;
360+
361+ rewrite_list_as_array_brackets ( & ty)
362+ }
363+
364+ /// Rewrites `List<T>` as `T[]`. Handles nesting (e.g. `List<List<Vector>>` becomes `Vector[][]`).
365+ /// Respects word boundaries so unrelated identifiers that happen to end in `List` are not affected.
366+ fn rewrite_list_as_array_brackets ( input : & str ) -> String {
367+ let bytes = input. as_bytes ( ) ;
368+ let mut result = String :: with_capacity ( input. len ( ) ) ;
369+ let mut i = 0 ;
370+
371+ while i < bytes. len ( ) {
372+ let at_word_boundary = i == 0 || !is_identifier_byte ( bytes[ i - 1 ] ) ;
373+ if at_word_boundary && bytes[ i..] . starts_with ( b"List<" ) {
374+ let inner_start = i + b"List<" . len ( ) ;
375+ if let Some ( close) = find_matching_angle_bracket ( bytes, inner_start) {
376+ let inner = & input[ inner_start..close] ;
377+ result. push_str ( & rewrite_list_as_array_brackets ( inner) ) ;
378+ result. push_str ( "[]" ) ;
379+ i = close + 1 ;
380+ continue ;
381+ }
382+ }
383+ if bytes[ i] . is_ascii ( ) {
384+ result. push ( bytes[ i] as char ) ;
385+ i += 1 ;
386+ } else {
387+ let ch = input[ i..] . chars ( ) . next ( ) . unwrap ( ) ;
388+ result. push ( ch) ;
389+ i += ch. len_utf8 ( ) ;
390+ }
391+ }
392+
393+ result
394+ }
395+
396+ fn is_identifier_byte ( byte : u8 ) -> bool {
397+ byte. is_ascii_alphanumeric ( ) || byte == b'_'
398+ }
399+
400+ fn find_matching_angle_bracket ( bytes : & [ u8 ] , start : usize ) -> Option < usize > {
401+ let mut depth = 1_usize ;
402+ for ( offset, & byte) in bytes[ start..] . iter ( ) . enumerate ( ) {
403+ match byte {
404+ b'<' => depth += 1 ,
405+ b'>' => {
406+ depth -= 1 ;
407+ if depth == 0 {
408+ return Some ( start + offset) ;
409+ }
410+ }
411+ _ => { }
412+ }
413+ }
414+ None
351415}
352416
353417impl std:: fmt:: Debug for Type {
@@ -359,18 +423,10 @@ impl std::fmt::Debug for Type {
359423// Display
360424impl std:: fmt:: Display for Type {
361425 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
362- use glam:: * ;
363-
364426 match self {
365427 Type :: Generic ( name) => write ! ( f, "{}" , make_type_user_readable( name) ) ,
366- Type :: Concrete ( ty) => match ( ) {
367- ( ) if self == & concrete ! ( DVec2 ) || self == & concrete ! ( Vec2 ) || self == & concrete ! ( IVec2 ) || self == & concrete ! ( UVec2 ) => write ! ( f, "Vec2" ) ,
368- ( ) if self == & concrete ! ( glam:: DAffine2 ) => write ! ( f, "Transform" ) ,
369- ( ) if self == & concrete ! ( Footprint ) => write ! ( f, "Footprint" ) ,
370- ( ) if self == & concrete ! ( & str ) || self == & concrete ! ( String ) => write ! ( f, "String" ) ,
371- _ => write ! ( f, "{}" , make_type_user_readable( & simplify_identifier_name( & ty. name) ) ) ,
372- } ,
373- Type :: Fn ( call_arg, return_value) => write ! ( f, "{return_value} called with {call_arg}" ) ,
428+ Type :: Concrete ( ty) => write ! ( f, "{ty}" ) ,
429+ Type :: Fn ( _, return_value) => write ! ( f, "{return_value}" ) ,
374430 Type :: Future ( ty) => write ! ( f, "{ty}" ) ,
375431 }
376432 }
0 commit comments