@@ -200,7 +200,13 @@ defprotocol Inspect do
200200 do: var! ( info )
201201
202202 var! ( name ) = Macro . inspect_atom ( :literal , unquote ( module ) )
203- unquote ( inspect_module ) . inspect ( var! ( struct ) , var! ( name ) , var! ( infos ) , var! ( opts ) )
203+
204+ unquote ( inspect_module ) . inspect_as_struct (
205+ var! ( struct ) ,
206+ var! ( name ) ,
207+ var! ( infos ) ,
208+ var! ( opts )
209+ )
204210 end
205211 end
206212 end
390396
391397defimpl Inspect , for: Map do
392398 def inspect ( map , opts ) do
399+ inspect_as_map ( map , opts )
400+ end
401+
402+ def inspect_as_map ( map , opts ) do
393403 list =
394404 if Keyword . get ( opts . custom_options , :sort_maps ) do
395405 map |> Map . to_list ( ) |> :lists . sort ( )
@@ -408,7 +418,7 @@ defimpl Inspect, for: Map do
408418 map_container_doc ( list , "" , opts , fun )
409419 end
410420
411- def inspect ( map , name , infos , opts ) do
421+ def inspect_as_struct ( map , name , infos , opts ) do
412422 fun = fn % { field: field } , opts -> Inspect.List . keyword ( { field , Map . get ( map , field ) } , opts ) end
413423 map_container_doc ( infos , name , opts , fun )
414424 end
@@ -599,25 +609,36 @@ end
599609defimpl Inspect , for: Any do
600610 def inspect ( % module { } = struct , opts ) do
601611 try do
602- { module . __struct__ ( ) , module . __info__ ( :struct ) }
612+ module . __info__ ( :struct )
603613 rescue
604- _ -> Inspect.Map . inspect ( struct , opts )
614+ _ -> Inspect.Map . inspect_as_map ( struct , opts )
605615 else
606- { dunder , fields } ->
607- if Map . keys ( dunder ) == Map . keys ( struct ) do
608- infos =
609- for % { field: field } = info <- fields ,
610- field not in [ :__struct__ , : __exception__] ,
611- do: info
612-
613- Inspect.Map . inspect ( struct , Macro . inspect_atom ( :literal , module ) , infos , opts )
616+ info ->
617+ if valid_struct? ( info , struct ) do
618+ info =
619+ for % { field: field } = map <- info ,
620+ field != : __exception__,
621+ do: map
622+
623+ Inspect.Map . inspect_as_struct ( struct , Macro . inspect_atom ( :literal , module ) , info , opts )
614624 else
615- Inspect.Map . inspect ( struct , opts )
625+ Inspect.Map . inspect_as_map ( struct , opts )
616626 end
617627 end
618628 end
619629
620- def inspect ( map , name , infos , opts ) do
630+ defp valid_struct? ( info , struct ) , do: valid_struct? ( info , struct , map_size ( struct ) - 1 )
631+
632+ defp valid_struct? ( [ % { field: field } | info ] , struct , count ) when is_map_key ( struct , field ) ,
633+ do: valid_struct? ( info , struct , count - 1 )
634+
635+ defp valid_struct? ( [ ] , _struct , 0 ) ,
636+ do: true
637+
638+ defp valid_struct? ( _fields , _struct , _count ) ,
639+ do: false
640+
641+ def inspect_as_struct ( map , name , infos , opts ) do
621642 open = color_doc ( "#" <> name <> "<" , :map , opts )
622643 sep = color_doc ( "," , :map , opts )
623644 close = color_doc ( ">" , :map , opts )
@@ -631,6 +652,25 @@ defimpl Inspect, for: Any do
631652 end
632653end
633654
655+ defimpl Inspect , for: Range do
656+ import Inspect.Algebra
657+ import Kernel , except: [ inspect: 2 ]
658+
659+ def inspect ( first .. last // 1 , opts ) when last >= first do
660+ concat ( [ to_doc ( first , opts ) , ".." , to_doc ( last , opts ) ] )
661+ end
662+
663+ def inspect ( first .. last // step , opts ) do
664+ concat ( [ to_doc ( first , opts ) , ".." , to_doc ( last , opts ) , "//" , to_doc ( step , opts ) ] )
665+ end
666+
667+ # TODO: Remove me on v2.0
668+ def inspect ( % { __struct__: Range , first: first , last: last } = range , opts ) do
669+ step = if first <= last , do: 1 , else: - 1
670+ inspect ( Map . put ( range , :step , step ) , opts )
671+ end
672+ end
673+
634674require Protocol
635675
636676Protocol . derive (
0 commit comments