|
| 1 | +use bindgen::callbacks::TypeKind; |
1 | 2 | use bindgen::{
|
2 | 3 | builder, AliasVariation, Builder, CodegenConfig, EnumVariation,
|
3 |
| - MacroTypeVariation, NonCopyUnionStyle, RustTarget, |
| 4 | + MacroTypeVariation, NonCopyUnionStyle, RegexSet, RustTarget, |
4 | 5 | DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS,
|
5 | 6 | };
|
6 | 7 | use clap::{App, Arg};
|
@@ -206,12 +207,26 @@ where
|
206 | 207 | .help("Avoid deriving Copy on any type."),
|
207 | 208 | Arg::new("with-derive-custom")
|
208 | 209 | .long("with-derive-custom")
|
209 |
| - .help( |
210 |
| - "Derive custom traits on any kind of type. \ |
211 |
| - The derive value must be of the shape <regex>=<kind>=<derive> where <kind> can be one of: \ |
212 |
| - Any, Struct, or Union.", |
213 |
| - ) |
214 |
| - .value_name("trait") |
| 210 | + .help( "Derive custom traits on any type whose name matches <regex>. The <derives> value must be of the shape <regex>=<traits> where <derives> is a comma-separated list of traits.") |
| 211 | + .value_name("derives") |
| 212 | + .multiple_occurrences(true) |
| 213 | + .number_of_values(1), |
| 214 | + Arg::new("with-derive-custom-struct") |
| 215 | + .long("with-derive-custom-struct") |
| 216 | + .help( "Derive custom traits on any `struct` whose name matches <regex>. The <derives> value must be of the shape <regex>=<traits> where <derives> is a comma-separated list of traits.") |
| 217 | + .value_name("derives") |
| 218 | + .multiple_occurrences(true) |
| 219 | + .number_of_values(1), |
| 220 | + Arg::new("with-derive-custom-enum") |
| 221 | + .long("with-derive-custom-enum") |
| 222 | + .help( "Derive custom traits on any `enum` whose name matches <regex>. The <derives> value must be of the shape <regex>=<traits> where <derives> is a comma-separated list of traits.") |
| 223 | + .value_name("derives") |
| 224 | + .multiple_occurrences(true) |
| 225 | + .number_of_values(1), |
| 226 | + Arg::new("with-derive-custom-union") |
| 227 | + .long("with-derive-custom-union") |
| 228 | + .help( "Derive custom traits on any `union` whose name matches <regex>. The <derives> value must be of the shape <regex>=<traits> where <derives> is a comma-separated list of traits.") |
| 229 | + .value_name("derives") |
215 | 230 | .multiple_occurrences(true)
|
216 | 231 | .number_of_values(1),
|
217 | 232 | Arg::new("no-derive-debug")
|
@@ -1102,52 +1117,62 @@ where
|
1102 | 1117 | builder = builder.wrap_unsafe_ops(true);
|
1103 | 1118 | }
|
1104 | 1119 |
|
1105 |
| - if let Some(custom_derives) = matches.values_of("with-derive-custom") { |
1106 |
| - #[derive(Debug)] |
1107 |
| - struct CustomDeriveCallback { |
1108 |
| - derive: String, |
1109 |
| - kind: String, |
1110 |
| - regex: String, |
1111 |
| - } |
1112 |
| - impl bindgen::callbacks::ParseCallbacks for CustomDeriveCallback { |
1113 |
| - fn add_derives(&self, info: &bindgen::callbacks::DeriveInfo<'_>) -> Vec<String> { |
1114 |
| - match self.kind.to_lowercase().as_str() { |
1115 |
| - "struct" => match info.kind { |
1116 |
| - Some(bindgen::ir::comp::CompKind::Struct) => {}, // continue |
1117 |
| - _ => return vec![], // bail |
1118 |
| - } |
1119 |
| - "union" => match info.kind { |
1120 |
| - Some(bindgen::ir::comp::CompKind::Union) => {}, // continue |
1121 |
| - _ => return vec![], // bail |
1122 |
| - } |
1123 |
| - "any" => {} // continue |
1124 |
| - other => panic!("Invalid custom derive: Unexpected kind '{}'", other) |
1125 |
| - } |
1126 |
| - |
1127 |
| - let mut re = bindgen::RegexSet::new(); |
1128 |
| - re.insert(self.regex.to_owned()); |
1129 |
| - re.build(false); |
1130 |
| - |
1131 |
| - match re.matches(info.name) { |
1132 |
| - true => vec![self.derive.to_owned()], |
1133 |
| - false => vec![], |
| 1120 | + #[derive(Debug)] |
| 1121 | + struct CustomDeriveCallback { |
| 1122 | + derives: Vec<String>, |
| 1123 | + kind: Option<TypeKind>, |
| 1124 | + regex_set: bindgen::RegexSet, |
| 1125 | + } |
| 1126 | + |
| 1127 | + impl bindgen::callbacks::ParseCallbacks for CustomDeriveCallback { |
| 1128 | + fn add_derives( |
| 1129 | + &self, |
| 1130 | + info: &bindgen::callbacks::DeriveInfo<'_>, |
| 1131 | + ) -> Vec<String> { |
| 1132 | + if self.kind.map(|kind| kind == info.kind).unwrap_or(true) { |
| 1133 | + if self.regex_set.matches(info.name) { |
| 1134 | + return self.derives.clone(); |
1134 | 1135 | }
|
1135 | 1136 | }
|
| 1137 | + vec![] |
1136 | 1138 | }
|
| 1139 | + } |
1137 | 1140 |
|
1138 |
| - for custom_derive in custom_derives { |
1139 |
| - let mut values = custom_derive.rsplitn(3, "="); |
1140 |
| - let derive = values.next().expect("Invalid custom derive: Expected 3 parts, found 0").to_owned(); |
1141 |
| - let kind = values.next().expect("Invalid custom derive: Expected 3 parts, found 1").to_owned(); |
1142 |
| - let regex = values.next().expect("Invalid custom derive: Expected 3 parts, found 2").to_owned(); |
1143 |
| - |
1144 |
| - builder = builder.parse_callbacks(Box::new(CustomDeriveCallback { derive, kind, regex: regex })); |
| 1141 | + for (values, kind) in [ |
| 1142 | + (matches.values_of("with-derive-custom"), None), |
| 1143 | + ( |
| 1144 | + matches.values_of("with-derive-custom-struct"), |
| 1145 | + Some(TypeKind::Struct), |
| 1146 | + ), |
| 1147 | + ( |
| 1148 | + matches.values_of("with-derive-custom-enum"), |
| 1149 | + Some(TypeKind::Enum), |
| 1150 | + ), |
| 1151 | + ( |
| 1152 | + matches.values_of("with-derive-custom-union"), |
| 1153 | + Some(TypeKind::Union), |
| 1154 | + ), |
| 1155 | + ] { |
| 1156 | + if let Some(custom_derives) = values { |
| 1157 | + for custom_derive in custom_derives { |
| 1158 | + let (regex, derives) = custom_derive |
| 1159 | + .rsplit_once("=") |
| 1160 | + .expect("Invalid custom derive argument: Missing `=`"); |
| 1161 | + let derives = |
| 1162 | + derives.split(",").map(|s| s.to_owned()).collect(); |
| 1163 | + |
| 1164 | + let mut regex_set = RegexSet::new(); |
| 1165 | + regex_set.insert(regex); |
| 1166 | + regex_set.build(false); |
| 1167 | + |
| 1168 | + builder = |
| 1169 | + builder.parse_callbacks(Box::new(CustomDeriveCallback { |
| 1170 | + derives, |
| 1171 | + kind, |
| 1172 | + regex_set, |
| 1173 | + })); |
| 1174 | + } |
1145 | 1175 | }
|
1146 |
| - |
1147 |
| - |
1148 |
| - |
1149 |
| - // let derives: Vec<String> = traits.into_iter().map(|t| t.to_string()).collect(); |
1150 |
| - // builder = builder.parse_callbacks(Box::new(CustomTraitCallback { derives })); |
1151 | 1176 | }
|
1152 | 1177 |
|
1153 | 1178 | Ok((builder, output, verbose))
|
|
0 commit comments