Skip to content

Commit fc1adb5

Browse files
committed
Use "rules" for config.
1 parent 23dc9ab commit fc1adb5

File tree

6 files changed

+97
-101
lines changed

6 files changed

+97
-101
lines changed

java-spaghetti-gen/src/config.rs

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! java-spaghetti.toml configuration file structures and parsing APIs.
22
3-
use std::collections::HashSet;
43
use std::path::{Path, PathBuf};
54
use std::{fs, io};
65

@@ -10,9 +9,6 @@ fn default_proxy_path_prefix() -> String {
109
"java_spaghetti/proxy".to_string()
1110
}
1211

13-
fn default_empty() -> String {
14-
String::new()
15-
}
1612
fn default_slash() -> String {
1713
String::from("/")
1814
}
@@ -73,16 +69,6 @@ pub struct DocPattern {
7369
/// | jni_prefix = "" | field_url_pattern = "https://developer.android.com/reference/{CLASS}.html#{FIELD}"
7470
pub field_url_pattern: Option<String>,
7571

76-
/// What java class(es) to match against. This takes the form of a simple prefix to a JNI path with no wildcards.
77-
///
78-
/// | To Match: | Use a JNI Prefix: |
79-
/// | ------------------------- | ------------------------------------- |
80-
/// | * | jni_prefix = ""
81-
/// | java.lang.* | jni_prefix = "java/lang/"
82-
/// | name.spaces.OuterClass.* | jni_prefix = "name/spaces/OuterClass$"
83-
#[serde(default = "default_empty")]
84-
pub jni_prefix: String,
85-
8672
/// What to use in the {CLASS} portion of URLs to separate namespaces. Defaults to "/".
8773
#[serde(default = "default_slash")]
8874
pub class_namespace_separator: String,
@@ -104,6 +90,35 @@ pub struct DocPattern {
10490
pub argument_seperator: String,
10591
}
10692

93+
#[derive(Debug, Clone, Deserialize)]
94+
pub struct Rule {
95+
/// What java class(es) to match against. This takes the form of a simple prefix to a JNI path with no wildcards.
96+
///
97+
/// | To Match: | Use a JNI Prefix: |
98+
/// | ------------------------- | ------------------------------------- |
99+
/// | * | jni_prefix = ""
100+
/// | java.lang.* | jni_prefix = "java/lang/"
101+
/// | name.spaces.OuterClass.* | jni_prefix = "name/spaces/OuterClass$"
102+
#[serde(default)]
103+
pub prefix: String,
104+
105+
#[serde(default)]
106+
pub include: Option<bool>,
107+
108+
#[serde(default)]
109+
pub proxy: Option<bool>,
110+
111+
#[serde(default)]
112+
pub doc_pattern: Option<DocPattern>,
113+
}
114+
115+
#[derive(Debug, Clone)]
116+
pub struct ClassConfig<'a> {
117+
pub include: bool,
118+
pub proxy: bool,
119+
pub doc_pattern: Option<&'a DocPattern>,
120+
}
121+
107122
#[derive(Debug, Clone, Deserialize)]
108123
pub struct Config {
109124
#[serde(default = "default_proxy_path_prefix")]
@@ -112,18 +127,11 @@ pub struct Config {
112127
pub(crate) input: Vec<PathBuf>,
113128
pub(crate) output: PathBuf,
114129

115-
#[serde(default)]
116-
pub(crate) doc_patterns: Vec<DocPattern>,
117130
#[serde(default)]
118131
pub(crate) logging_verbose: bool,
119132

120-
#[serde(rename = "include")]
121133
#[serde(default)]
122-
pub(crate) include_classes: HashSet<String>,
123-
124-
#[serde(rename = "include_proxy")]
125-
#[serde(default = "HashSet::new")]
126-
pub(crate) include_proxies: HashSet<String>,
134+
pub(crate) rules: Vec<Rule>,
127135
}
128136

129137
impl Config {
@@ -140,8 +148,13 @@ impl Config {
140148
pub fn read_str(buffer: &str, dir: &Path) -> io::Result<Self> {
141149
let mut config: Config = toml::from_str(buffer).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
142150

143-
if config.include_classes.is_empty() {
144-
config.include_classes.insert("*".to_string());
151+
if config.rules.is_empty() {
152+
config.rules.push(Rule {
153+
prefix: "".to_string(),
154+
include: Some(true),
155+
doc_pattern: None,
156+
proxy: None,
157+
})
145158
}
146159

147160
config.output = resolve_file(&config.output, dir);
@@ -181,6 +194,30 @@ impl Config {
181194
}
182195
}
183196
}
197+
198+
pub fn resolve_class(&self, class: &str) -> ClassConfig<'_> {
199+
let mut res = ClassConfig {
200+
include: false,
201+
proxy: false,
202+
doc_pattern: None,
203+
};
204+
205+
for r in &self.rules {
206+
if class.starts_with(&r.prefix) {
207+
if let Some(include) = r.include {
208+
res.include = include;
209+
}
210+
if let Some(proxy) = r.proxy {
211+
res.proxy = proxy;
212+
}
213+
if let Some(doc_pattern) = &r.doc_pattern {
214+
res.doc_pattern = Some(doc_pattern);
215+
}
216+
}
217+
}
218+
219+
res
220+
}
184221
}
185222

186223
fn resolve_file(path: &Path, dir: &Path) -> PathBuf {

java-spaghetti-gen/src/emit_rust/classes.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ pub(crate) struct StructPaths {
2020
}
2121

2222
impl StructPaths {
23-
pub(crate) fn new(context: &Context, class: Id) -> Result<Self, Box<dyn Error>> {
23+
pub(crate) fn new(class: Id) -> Result<Self, Box<dyn Error>> {
2424
Ok(Self {
25-
mod_: Class::mod_for(context, class)?,
26-
struct_name: Class::name_for(context, class)?,
25+
mod_: Class::mod_for(class)?,
26+
struct_name: Class::name_for(class)?,
2727
})
2828
}
2929
}
@@ -47,7 +47,7 @@ fn rust_id(id: &str) -> Result<String, Box<dyn Error>> {
4747
}
4848

4949
impl Class {
50-
pub(crate) fn mod_for(_context: &Context, class: Id) -> Result<String, Box<dyn Error>> {
50+
pub(crate) fn mod_for(class: Id) -> Result<String, Box<dyn Error>> {
5151
let mut buf = String::new();
5252
for component in class {
5353
match component {
@@ -64,7 +64,7 @@ impl Class {
6464
Ok(buf)
6565
}
6666

67-
pub(crate) fn name_for(_context: &Context, class: Id) -> Result<String, Box<dyn Error>> {
67+
pub(crate) fn name_for(class: Id) -> Result<String, Box<dyn Error>> {
6868
let mut buf = String::new();
6969
for component in class.iter() {
7070
match component {
@@ -76,13 +76,15 @@ impl Class {
7676
Ok(buf)
7777
}
7878

79-
pub(crate) fn new(context: &mut Context, java: JavaClass) -> Result<Self, Box<dyn Error>> {
80-
let rust = StructPaths::new(context, java.path())?;
79+
pub(crate) fn new(java: JavaClass) -> Result<Self, Box<dyn Error>> {
80+
let rust = StructPaths::new(java.path())?;
8181

8282
Ok(Self { rust, java })
8383
}
8484

8585
pub(crate) fn write(&self, context: &Context) -> anyhow::Result<TokenStream> {
86+
let cc = context.config.resolve_class(self.java.path().as_str());
87+
8688
// Ignored access_flags: SUPER, SYNTHETIC, ANNOTATION, ABSTRACT
8789

8890
let keyword = if self.java.is_interface() {
@@ -103,7 +105,7 @@ impl Class {
103105
false => quote!(),
104106
};
105107

106-
let docs = match KnownDocsUrl::from_class(context, self.java.path()) {
108+
let docs = match KnownDocsUrl::from_class(&cc, self.java.path()) {
107109
Some(url) => format!("{visibility} {keyword} {url}"),
108110
None => format!("{visibility} {keyword} {}", self.java.path().as_str()),
109111
};
@@ -174,31 +176,31 @@ impl Class {
174176
let mut methods: Vec<Method> = self
175177
.java
176178
.methods()
177-
.map(|m| Method::new(context, &self.java, m))
179+
.map(|m| Method::new(&self.java, m))
178180
.filter(|m| m.java.is_public() && !m.java.is_bridge())
179181
.collect();
180182
let mut fields: Vec<Field> = self
181183
.java
182184
.fields()
183-
.map(|f| Field::new(context, &self.java, f))
185+
.map(|f| Field::new(&self.java, f))
184186
.filter(|f| f.java.is_public())
185187
.collect();
186188

187189
self.resolve_collisions(&mut methods, &fields)?;
188190

189191
for method in &mut methods {
190-
let res = method.emit(context, &self.rust.mod_).unwrap();
192+
let res = method.emit(context, &cc, &self.rust.mod_).unwrap();
191193
contents.extend(res);
192194
}
193195

194196
for field in &mut fields {
195-
let res = field.emit(context, &self.rust.mod_).unwrap();
197+
let res = field.emit(context, &cc, &self.rust.mod_).unwrap();
196198
contents.extend(res);
197199
}
198200

199201
out.extend(quote!(impl #rust_name { #contents }));
200202

201-
if context.proxy_included(self.java.path().as_str()) {
203+
if cc.proxy {
202204
out.extend(self.write_proxy(context, &methods)?);
203205
}
204206

java-spaghetti-gen/src/emit_rust/fields.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use quote::{format_ident, quote};
66

77
use super::cstring;
88
use super::known_docs_url::KnownDocsUrl;
9+
use crate::config::ClassConfig;
910
use crate::emit_rust::Context;
1011
use crate::identifiers::{FieldMangling, IdentifierManglingError, mangle_field};
1112
use crate::parser_util::{Id, JavaClass, JavaField};
@@ -17,15 +18,15 @@ pub struct Field<'a> {
1718
}
1819

1920
impl<'a> Field<'a> {
20-
pub fn new(_context: &Context, class: &'a JavaClass, java: &'a cafebabe::FieldInfo<'a>) -> Self {
21+
pub fn new(class: &'a JavaClass, java: &'a cafebabe::FieldInfo<'a>) -> Self {
2122
Self {
2223
class,
2324
java: JavaField::from(java),
2425
rust_names: mangle_field(JavaField::from(java)),
2526
}
2627
}
2728

28-
pub fn emit(&self, context: &Context, mod_: &str) -> anyhow::Result<TokenStream> {
29+
pub fn emit(&self, context: &Context, cc: &ClassConfig, mod_: &str) -> anyhow::Result<TokenStream> {
2930
let mut emit_reject_reasons = Vec::new();
3031

3132
if !self.java.is_public() {
@@ -91,7 +92,7 @@ impl<'a> Field<'a> {
9192
};
9293

9394
let docs = match KnownDocsUrl::from_field(
94-
context,
95+
cc,
9596
self.class.path().as_str(),
9697
self.java.name(),
9798
self.java.descriptor().clone(),

java-spaghetti-gen/src/emit_rust/known_docs_url.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::fmt::{self, Display, Formatter};
33
use cafebabe::descriptors::{FieldDescriptor, FieldType};
44

55
use super::methods::Method;
6-
use crate::emit_rust::Context;
6+
use crate::config::ClassConfig;
77
use crate::parser_util::Id;
88

99
pub(crate) struct KnownDocsUrl {
@@ -18,13 +18,9 @@ impl Display for KnownDocsUrl {
1818
}
1919

2020
impl KnownDocsUrl {
21-
pub(crate) fn from_class(context: &Context, java_class: Id) -> Option<KnownDocsUrl> {
21+
pub(crate) fn from_class(config: &ClassConfig, java_class: Id) -> Option<KnownDocsUrl> {
2222
let java_class = java_class.as_str();
23-
let pattern = context
24-
.config
25-
.doc_patterns
26-
.iter()
27-
.find(|pattern| java_class.starts_with(pattern.jni_prefix.as_str()))?;
23+
let pattern = config.doc_pattern?;
2824

2925
for ch in java_class.chars() {
3026
match ch {
@@ -56,14 +52,10 @@ impl KnownDocsUrl {
5652
})
5753
}
5854

59-
pub(crate) fn from_method(context: &Context, method: &Method) -> Option<KnownDocsUrl> {
55+
pub(crate) fn from_method(config: &ClassConfig, method: &Method) -> Option<KnownDocsUrl> {
6056
let is_constructor = method.java.is_constructor();
6157

62-
let pattern = context
63-
.config
64-
.doc_patterns
65-
.iter()
66-
.find(|pattern| method.class.path().as_str().starts_with(pattern.jni_prefix.as_str()))?;
58+
let pattern = config.doc_pattern?;
6759
let url_pattern = if is_constructor {
6860
pattern
6961
.constructor_url_pattern
@@ -188,16 +180,12 @@ impl KnownDocsUrl {
188180
}
189181

190182
pub(crate) fn from_field(
191-
context: &Context,
183+
config: &ClassConfig,
192184
java_class: &str,
193185
java_field: &str,
194186
_java_descriptor: FieldDescriptor,
195187
) -> Option<KnownDocsUrl> {
196-
let pattern = context
197-
.config
198-
.doc_patterns
199-
.iter()
200-
.find(|pattern| java_class.starts_with(pattern.jni_prefix.as_str()))?;
188+
let pattern = config.doc_pattern?;
201189
let field_url_pattern = pattern.field_url_pattern.as_ref()?;
202190

203191
for ch in java_class.chars() {

java-spaghetti-gen/src/emit_rust/methods.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use quote::{format_ident, quote};
55
use super::cstring;
66
use super::fields::{RustTypeFlavor, emit_fragment_type, emit_rust_type};
77
use super::known_docs_url::KnownDocsUrl;
8+
use crate::config::ClassConfig;
89
use crate::emit_rust::Context;
910
use crate::identifiers::MethodManglingStyle;
1011
use crate::parser_util::{JavaClass, JavaMethod};
@@ -17,7 +18,7 @@ pub struct Method<'a> {
1718
}
1819

1920
impl<'a> Method<'a> {
20-
pub fn new(_context: &Context, class: &'a JavaClass, java: &'a cafebabe::MethodInfo<'a>) -> Self {
21+
pub fn new(class: &'a JavaClass, java: &'a cafebabe::MethodInfo<'a>) -> Self {
2122
let mut result = Self {
2223
class,
2324
java: JavaMethod::from(java),
@@ -40,7 +41,7 @@ impl<'a> Method<'a> {
4041
.ok()
4142
}
4243

43-
pub fn emit(&self, context: &Context, mod_: &str) -> anyhow::Result<TokenStream> {
44+
pub fn emit(&self, context: &Context, cc: &ClassConfig, mod_: &str) -> anyhow::Result<TokenStream> {
4445
let mut emit_reject_reasons = Vec::new();
4546

4647
let descriptor = self.java.descriptor();
@@ -123,7 +124,7 @@ impl<'a> Method<'a> {
123124
quote!()
124125
};
125126

126-
let docs = match KnownDocsUrl::from_method(context, self) {
127+
let docs = match KnownDocsUrl::from_method(cc, self) {
127128
Some(url) => format!("{url}"),
128129
None => self.java.name().to_string(),
129130
};

0 commit comments

Comments
 (0)