11from typing import Dict , Optional , Any , Union , List
22from lighttree import Node , Tree , Key
3+ from lighttree .node import NodeId
4+ from lighttree .interactive import TreeBasedObj
35
46
57class JsonTree (Tree ):
68 def __init__ (
7- self , d : Dict = None , strict : bool = True , path_separator : str = "."
9+ self , d : Optional [ Dict ] = None , strict : bool = True , path_separator : str = "."
810 ) -> None :
911 """
1012 :param d:
@@ -23,53 +25,63 @@ def _concat(a: Any, b: Any) -> str:
2325 return str (b )
2426 return "." .join ([str (a ), str (b )])
2527
26- def _fill (
27- self , data : Any , key : Key , strict : bool , path : Optional [str ] = None
28- ) -> None :
28+ def _fill (self , data : Any , key : Key , strict : bool , path : str = "" ) -> None :
29+ pid : Optional [NodeId ]
30+ if self .is_empty ():
31+ pid = None
32+ else :
33+ pid = self .get_node_id_by_path (path = path )
2934 if isinstance (data , list ) or not strict and isinstance (data , tuple ):
30- k = self .insert_node (
31- Node (keyed = False ), parent_id = path , key = key , by_path = True
32- )
35+ k = self .insert_node (Node (keyed = False ), parent_id = pid , key = key )
3336 path = self ._concat (path , k )
3437 for el in data :
3538 self ._fill (el , strict = strict , path = path , key = None )
3639 return
3740 if isinstance (data , dict ):
38- k = self .insert_node (
39- Node (keyed = True ), key = key , parent_id = path , by_path = True
40- )
41+ k = self .insert_node (Node (keyed = True ), key = key , parent_id = pid )
4142 path = self ._concat (path , k )
4243 for sk , el in data .items ():
4344 self ._fill (el , strict = strict , path = path , key = sk )
4445 return
4546 if isinstance (data , (str , int , float )):
4647 self .insert_node (
47- Node (accept_children = False , repr_ = data , data = data ),
48- parent_id = path ,
48+ Node (accept_children = False , repr_ = str ( data ) , data = data ),
49+ parent_id = pid ,
4950 key = key ,
50- by_path = True ,
5151 )
5252 return
5353 if data is None :
54- self .insert_node (Node (accept_children = False ), parent_id = path , by_path = True )
54+ self .insert_node (Node (accept_children = False ), parent_id = pid )
5555 return
5656 raise TypeError ("Unsupported type %s" % type (data ))
5757
58- def to_dict (self ) -> Union [Dict , List , None ]:
58+ def to_json (self ) -> Union [Dict , List , None ]:
5959 if self .root is None :
6060 return None
61- return self ._to_dict (self .root )
61+ return self ._to_json (self .root )
6262
63- def _to_dict (self , nid : str ) -> Any :
63+ def _to_json (self , nid : NodeId ) -> Any :
6464 _ , n = self .get (nid )
6565 if not n .accept_children :
6666 return n .data
6767 if n .keyed :
6868 d = {}
6969 for sk , sn in self .children (n .identifier ):
70- d [sk ] = self ._to_dict (sn .identifier )
70+ d [sk ] = self ._to_json (sn .identifier )
7171 return d
7272 l_ = []
7373 for _ , sn in self .children (n .identifier ):
74- l_ .append (self ._to_dict (sn .identifier ))
74+ l_ .append (self ._to_json (sn .identifier ))
7575 return l_
76+
77+
78+ class InteractiveJson (TreeBasedObj ):
79+
80+ _tree : JsonTree
81+
82+ def __call__ (self , * args : Any , ** kwargs : Any ) -> Any :
83+ return self ._tree .to_json ()
84+
85+
86+ def as_interactive_json (d : Any , strict : bool = False ) -> InteractiveJson :
87+ return InteractiveJson (tree = JsonTree (d , strict = strict ))
0 commit comments