@@ -27,6 +27,56 @@ fn member_to_ident(member: &syn::Member) -> String {
2727 }
2828}
2929
30+ // TODO: Maybe add support to more std associated constants.
31+ fn to_known_assoc_constant ( associated_to : & Path , name : & str ) -> Option < String > {
32+ use crate :: bindgen:: ir:: { IntKind , PrimitiveType } ;
33+
34+ if name != "MAX" && name != "MIN" {
35+ return None ;
36+ }
37+
38+ let prim = PrimitiveType :: maybe ( associated_to. name ( ) ) ?;
39+ let prefix = match prim {
40+ PrimitiveType :: Integer {
41+ kind,
42+ signed,
43+ zeroable : _,
44+ } => match kind {
45+ IntKind :: B8 => {
46+ if signed {
47+ "INT8"
48+ } else {
49+ "UINT8"
50+ }
51+ }
52+ IntKind :: B16 => {
53+ if signed {
54+ "INT16"
55+ } else {
56+ "UINT16"
57+ }
58+ }
59+ IntKind :: B32 => {
60+ if signed {
61+ "INT32"
62+ } else {
63+ "UINT32"
64+ }
65+ }
66+ IntKind :: B64 => {
67+ if signed {
68+ "INT64"
69+ } else {
70+ "UINT64"
71+ }
72+ }
73+ _ => return None ,
74+ } ,
75+ _ => return None ,
76+ } ;
77+ Some ( format ! ( "{}_{}" , prefix, name) )
78+ }
79+
3080#[ derive( Debug , Clone ) ]
3181pub enum Literal {
3282 Expr ( String ) ,
@@ -112,10 +162,12 @@ impl Literal {
112162 match * self {
113163 Literal :: Expr ( ..) => true ,
114164 Literal :: Path {
115- ref associated_to, ..
165+ ref associated_to,
166+ ref name,
116167 } => {
117168 if let Some ( ( ref path, _export_name) ) = associated_to {
118- return bindings. struct_exists ( path) ;
169+ return bindings. struct_exists ( path)
170+ || to_known_assoc_constant ( path, name) . is_some ( ) ;
119171 }
120172 true
121173 }
@@ -274,6 +326,30 @@ impl Literal {
274326 field : member_to_ident ( member) ,
275327 } ) ,
276328
329+ syn:: Expr :: Call ( syn:: ExprCall {
330+ ref func, ref args, ..
331+ } ) => {
332+ let struct_name = match Literal :: load ( func) ? {
333+ Literal :: Path {
334+ associated_to : None ,
335+ name,
336+ } => name,
337+ _ => return Err ( format ! ( "Unsupported call expression. {:?}" , * expr) ) ,
338+ } ;
339+ let mut fields = HashMap :: < String , Literal > :: default ( ) ;
340+ for ( index, arg) in args. iter ( ) . enumerate ( ) {
341+ let ident =
342+ member_to_ident ( & syn:: Member :: Unnamed ( syn:: Index :: from ( index) ) ) . to_string ( ) ;
343+ let value = Literal :: load ( arg) ?;
344+ fields. insert ( ident, value) ;
345+ }
346+ Ok ( Literal :: Struct {
347+ path : Path :: new ( struct_name. clone ( ) ) ,
348+ export_name : struct_name,
349+ fields,
350+ } )
351+ }
352+
277353 syn:: Expr :: Struct ( syn:: ExprStruct {
278354 ref path,
279355 ref fields,
@@ -282,10 +358,9 @@ impl Literal {
282358 let struct_name = path. segments [ 0 ] . ident . unraw ( ) . to_string ( ) ;
283359 let mut field_map = HashMap :: < String , Literal > :: default ( ) ;
284360 for field in fields {
285- let ident = member_to_ident ( & field. member ) ;
286- let key = ident. to_string ( ) ;
361+ let ident = member_to_ident ( & field. member ) . to_string ( ) ;
287362 let value = Literal :: load ( & field. expr ) ?;
288- field_map. insert ( key , value) ;
363+ field_map. insert ( ident , value) ;
289364 }
290365 Ok ( Literal :: Struct {
291366 path : Path :: new ( struct_name. clone ( ) ) ,
@@ -357,7 +432,10 @@ impl Literal {
357432 ref associated_to,
358433 ref name,
359434 } => {
360- if let Some ( ( _, ref export_name) ) = associated_to {
435+ if let Some ( ( ref path, ref export_name) ) = associated_to {
436+ if let Some ( known) = to_known_assoc_constant ( path, name) {
437+ return write ! ( out, "{}" , known) ;
438+ }
361439 let path_separator = match config. language {
362440 Language :: Cython | Language :: C => "_" ,
363441 Language :: Cxx => {
0 commit comments