1- use std:: ops:: Deref ;
2-
3- use pyo3:: types:: { PyList , PyString } ;
4- use pyo3:: { Python , pyclass, pymethods, types:: PyBytes } ;
1+ use pyo3:: types:: PyString ;
2+ use pyo3:: { Python , pyclass, pymethods} ;
53use pyo3:: { IntoPyObjectExt , prelude:: * } ;
64use whatsapp_rust:: NodeBuilder ;
75use crate :: types:: JID ;
@@ -69,9 +67,9 @@ impl NodeValue {
6967
7068/// NodeContent enum internal
7169pub enum NodeContentEnum {
72- Bytes ( Py < PyBytes > ) ,
73- String ( Py < PyString > ) ,
74- Nodes ( Py < PyList > ) , // PyList<Node>
70+ Bytes ( Py < Vec < u8 > > ) ,
71+ String ( String ) ,
72+ Nodes ( Vec < Py < Node > > ) , // PyList<Node>
7573}
7674
7775/// PyClass wrapper untuk NodeContent
@@ -84,11 +82,12 @@ pub struct NodeContent {
8482impl NodeContent {
8583 #[ getter]
8684 fn value ( & self , py : Python < ' _ > ) -> Py < PyAny > {
87- match & self . inner {
85+ let result = match & self . inner {
8886 NodeContentEnum :: Bytes ( b) => b. clone_ref ( py) . into_any ( ) ,
89- NodeContentEnum :: String ( s) => s. clone_ref ( py) . into_any ( ) ,
90- NodeContentEnum :: Nodes ( n) => n. clone_ref ( py) . into_any ( ) ,
91- }
87+ NodeContentEnum :: String ( s) => s. into_py_any ( py) . unwrap ( ) ,
88+ NodeContentEnum :: Nodes ( n) => n. into_py_any ( py) . unwrap ( ) ,
89+ } ;
90+ result
9291 }
9392
9493 pub fn is_bytes ( & self ) -> bool {
@@ -103,13 +102,14 @@ impl NodeContent {
103102 matches ! ( self . inner, NodeContentEnum :: Nodes ( _) )
104103 }
105104
106- // pub fn __repr__(&self, py: Python<'_>) -> String {
107- // match &self.inner {
108- // NodeContentEnum::Bytes(_) => "NodeContent::Bytes(...)".to_string(),
109- // NodeContentEnum::String(s) => format!("NodeContent::String({})", s),
110- // NodeContentEnum::Nodes(n) => format!("NodeContent::Nodes(len={})", n.len()),
111- // }
112- // }
105+ pub fn __repr__ ( & self , _py : Python < ' _ > ) -> PyResult < String > {
106+ let repr = match & self . inner {
107+ NodeContentEnum :: Bytes ( _) => "NodeContent::Bytes(...)" . to_string ( ) ,
108+ NodeContentEnum :: String ( s) => format ! ( "NodeContent::String({})" , s) ,
109+ NodeContentEnum :: Nodes ( n) => format ! ( "NodeContent::Nodes(len={})" , n. len( ) ) ,
110+ } ;
111+ Ok ( repr)
112+ }
113113}
114114
115115
@@ -118,40 +118,34 @@ pub struct Attrs {
118118 #[ pyo3( get, set) ]
119119 pub key : String ,
120120 #[ pyo3( get, set) ]
121- pub value : pyo3:: Py < PyList > , // PyList<NodeValue>
121+ pub value : Vec < pyo3:: Py < NodeValue > > , // PyList<NodeValue>
122122
123123}
124+ #[ pymethods]
125+ impl Attrs {
126+ #[ new]
127+ fn new ( key : String , value : Vec < Py < NodeValue > > ) -> Self {
128+ Attrs {
129+ key : key,
130+ value : value
131+ }
132+ }
133+ }
124134#[ pyclass]
125135pub struct Node {
126136 #[ pyo3( get, set) ]
127137 pub tag : String ,
128138 #[ pyo3( get, set) ]
129- pub attrs : Py < PyList > , // PyList<Attrs>
139+ pub attrs : Vec < Py < Attrs > > , // PyList<Attrs>
130140 #[ pyo3( get, set) ]
131- pub content : Py < PyAny > , // Py<PyAny> yang bisa berisi NodeContent atau None
141+ pub content : Option < Py < NodeContent > > , // Py<PyAny> yang bisa berisi NodeContent atau None
132142}
133143
134144#[ pymethods]
135145impl Node {
136146 #[ new]
137- pub fn new ( tag : String , attrs : Option < Py < PyList > > , content : Option < pyo3:: Py < NodeContent > > ) -> PyResult < Self > {
138- Python :: attach ( |py| {
139- let content_py = match content {
140- Some ( c) => c. into_any ( ) ,
141- None => py. None ( ) ,
142- } ;
143- let attrs_py = match attrs {
144- Some ( a) => {
145- let list = a. clone_ref ( py) ;
146- for item in list. bind ( py) . iter ( ) {
147- let _ = item. extract :: < Py < Attrs > > ( ) ?;
148- } ;
149- list
150- } ,
151- None => PyList :: empty ( py) . unbind ( ) ,
152- } ;
153- Ok ( Self { tag, attrs : attrs_py, content : content_py } )
154- } )
147+ pub fn new ( tag : String , attrs : Vec < Py < Attrs > > , content : Option < pyo3:: Py < NodeContent > > ) -> Self {
148+ Self { tag, attrs : attrs, content : content }
155149 }
156150
157151 // pub fn __repr__(&self, py: Python<'_>) -> String {
@@ -167,6 +161,7 @@ impl Node {
167161impl Node {
168162 pub fn to_node_builder ( & self , py : Python < ' _ > ) -> NodeBuilder {
169163 let mut builder = NodeBuilder :: new ( self . tag . clone ( ) ) ;
164+
170165 if let Some ( content) = & self . content {
171166 let content_ref = content. bind ( py) . borrow ( ) ;
172167 match & content_ref. inner {
@@ -175,21 +170,66 @@ impl Node {
175170 builder = builder. bytes ( b_extract) ;
176171 }
177172 NodeContentEnum :: String ( s) => {
178- let s_extract = s. to_str ( py) . unwrap ( ) ;
179- builder = builder. string_content ( s_extract) ;
173+ builder = builder. string_content ( s. clone ( ) ) ;
180174 }
181175 NodeContentEnum :: Nodes ( n) => {
182- n. bind ( py) . iter ( ) . for_each ( |item| {
183- let it= item. extract ( ) ;
184- } ) ;
176+ let nodes_extract = n
177+ . iter ( )
178+ . map ( |node| {
179+ let node_ref = node. bind ( py) . borrow ( ) ;
180+ node_ref. to_node_builder ( py) . build ( )
181+ } )
182+ . collect :: < Vec < _ > > ( ) ;
183+ builder = builder. children ( nodes_extract) ;
185184 }
185+ } ;
186+ }
187+
188+ for attr in & self . attrs {
189+ let attr_ref = attr. bind ( py) . borrow ( ) ;
190+ if attr_ref. value . len ( ) == 1 {
191+ let value_ref = attr_ref. value [ 0 ] . bind ( py) . borrow ( ) ;
192+ builder = match & value_ref. inner {
193+ NodeValueEnum :: String ( s) => builder. attr ( attr_ref. key . clone ( ) , s. clone ( ) ) ,
194+ NodeValueEnum :: Jid ( jid) => {
195+ let jid_ref = jid. bind ( py) . borrow ( ) ;
196+ builder. jid_attr ( attr_ref. key . clone ( ) , jid_ref. as_whatsapp_jid ( ) )
197+ }
198+ } ;
199+ } else {
200+ let joined = attr_ref
201+ . value
202+ . iter ( )
203+ . map ( |v| {
204+ let v_ref = v. bind ( py) . borrow ( ) ;
205+ match & v_ref. inner {
206+ NodeValueEnum :: String ( s) => s. clone ( ) ,
207+ NodeValueEnum :: Jid ( jid) => {
208+ let jid_ref = jid. bind ( py) . borrow ( ) ;
209+ jid_ref. as_whatsapp_jid ( ) . to_string ( )
210+ }
211+ }
212+ } )
213+ . collect :: < Vec < _ > > ( )
214+ . join ( "," ) ;
215+ builder = builder. attr ( attr_ref. key . clone ( ) , joined) ;
186216 }
187217 }
218+
188219 builder
189220 }
221+
190222 pub fn from_node_builder ( builder : NodeBuilder ) -> Self {
191223 let node = builder. build ( ) ;
192- Self { tag : node. tag , content : node. content }
193224
225+ Self {
226+ tag : node. tag ,
227+ attrs : Vec :: new ( ) ,
228+ content : None ,
229+ }
230+ }
231+
232+ pub fn from_node ( node : wacore_binary:: node:: Node ) -> Self {
233+ //
194234 }
195235}
0 commit comments