alef_core/config/resolved/
ffi.rs1use super::ResolvedCrateConfig;
4
5impl ResolvedCrateConfig {
6 pub fn ffi_prefix(&self) -> String {
11 self.ffi
12 .as_ref()
13 .and_then(|f| f.prefix.as_ref())
14 .cloned()
15 .unwrap_or_else(|| self.name.replace('-', "_"))
16 }
17
18 pub fn ffi_lib_name(&self) -> String {
28 if let Some(name) = self.ffi.as_ref().and_then(|f| f.lib_name.as_ref()) {
30 return name.clone();
31 }
32
33 if let Some(ffi_path) = self.explicit_output.ffi.as_ref() {
37 let crate_dir = ffi_path
38 .components()
39 .filter_map(|c| {
40 if let std::path::Component::Normal(s) = c {
41 s.to_str()
42 } else {
43 None
44 }
45 })
46 .rev()
47 .find(|&s| s != "src" && s != "lib" && s != "include");
48 if let Some(dir) = crate_dir {
49 return dir.replace('-', "_");
50 }
51 }
52
53 format!("{}_ffi", self.ffi_prefix())
55 }
56
57 pub fn ffi_header_name(&self) -> String {
61 self.ffi
62 .as_ref()
63 .and_then(|f| f.header_name.as_ref())
64 .cloned()
65 .unwrap_or_else(|| format!("{}.h", self.ffi_prefix()))
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use crate::config::new_config::NewAlefConfig;
72
73 fn resolved_one(toml: &str) -> super::super::ResolvedCrateConfig {
74 let cfg: NewAlefConfig = toml::from_str(toml).unwrap();
75 cfg.resolve().unwrap().remove(0)
76 }
77
78 fn minimal_ffi() -> super::super::ResolvedCrateConfig {
79 resolved_one(
80 r#"
81[workspace]
82languages = ["ffi"]
83
84[[crates]]
85name = "my-lib"
86sources = ["src/lib.rs"]
87"#,
88 )
89 }
90
91 #[test]
92 fn ffi_prefix_defaults_to_snake_case_name() {
93 let r = minimal_ffi();
94 assert_eq!(r.ffi_prefix(), "my_lib");
95 }
96
97 #[test]
98 fn ffi_prefix_explicit_wins() {
99 let r = resolved_one(
100 r#"
101[workspace]
102languages = ["ffi"]
103
104[[crates]]
105name = "my-lib"
106sources = ["src/lib.rs"]
107
108[crates.ffi]
109prefix = "custom_prefix"
110"#,
111 );
112 assert_eq!(r.ffi_prefix(), "custom_prefix");
113 }
114
115 #[test]
116 fn ffi_lib_name_falls_back_to_prefix_ffi() {
117 let r = minimal_ffi();
118 assert_eq!(r.ffi_lib_name(), "my_lib_ffi");
119 }
120
121 #[test]
122 fn ffi_lib_name_explicit_wins() {
123 let r = resolved_one(
124 r#"
125[workspace]
126languages = ["ffi"]
127
128[[crates]]
129name = "my-lib"
130sources = ["src/lib.rs"]
131
132[crates.ffi]
133lib_name = "libmy_custom"
134"#,
135 );
136 assert_eq!(r.ffi_lib_name(), "libmy_custom");
137 }
138
139 #[test]
140 fn ffi_header_name_defaults_to_prefix_h() {
141 let r = minimal_ffi();
142 assert_eq!(r.ffi_header_name(), "my_lib.h");
143 }
144
145 #[test]
146 fn ffi_lib_name_derives_from_explicit_output_path() {
147 let r = resolved_one(
148 r#"
149[workspace]
150languages = ["ffi"]
151
152[[crates]]
153name = "my-lib"
154sources = ["src/lib.rs"]
155
156[crates.output]
157ffi = "crates/html-to-markdown-ffi/src/"
158"#,
159 );
160 assert_eq!(r.ffi_lib_name(), "html_to_markdown_ffi");
163 }
164
165 #[test]
166 fn ffi_lib_name_explicit_lib_name_overrides_output_path_derivation() {
167 let r = resolved_one(
168 r#"
169[workspace]
170languages = ["ffi"]
171
172[[crates]]
173name = "my-lib"
174sources = ["src/lib.rs"]
175
176[crates.ffi]
177lib_name = "explicit_wins"
178
179[crates.output]
180ffi = "crates/html-to-markdown-ffi/src/"
181"#,
182 );
183 assert_eq!(r.ffi_lib_name(), "explicit_wins");
185 }
186
187 #[test]
188 fn ffi_lib_name_template_derived_output_does_not_drive_lib_name() {
189 let r = minimal_ffi();
193 assert_eq!(r.ffi_lib_name(), "my_lib_ffi");
194 }
195
196 #[test]
197 fn ffi_header_name_explicit_wins() {
198 let r = resolved_one(
199 r#"
200[workspace]
201languages = ["ffi"]
202
203[[crates]]
204name = "my-lib"
205sources = ["src/lib.rs"]
206
207[crates.ffi]
208header_name = "custom.h"
209"#,
210 );
211 assert_eq!(r.ffi_header_name(), "custom.h");
212 }
213}