Skip to content

Commit d5eca4e

Browse files
freopendwrensha
authored andcommitted
Add raw schema output option to capnpc.
1 parent 933f358 commit d5eca4e

File tree

5 files changed

+65
-0
lines changed

5 files changed

+65
-0
lines changed

capnpc/src/codegen.rs

+29
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use self::FormattedText::{Indent, Line, Branch, BlankLine};
3636
pub struct CodeGenerationCommand {
3737
output_directory: PathBuf,
3838
default_parent_module: Vec<String>,
39+
raw_code_generator_request_path: Option<PathBuf>,
3940
}
4041

4142
impl CodeGenerationCommand {
@@ -44,6 +45,7 @@ impl CodeGenerationCommand {
4445
CodeGenerationCommand {
4546
output_directory: PathBuf::new(),
4647
default_parent_module: Vec::new(),
48+
raw_code_generator_request_path: None,
4749
}
4850
}
4951

@@ -65,6 +67,14 @@ impl CodeGenerationCommand {
6567
self
6668
}
6769

70+
/// Sets the raw code generator request output path.
71+
pub fn raw_code_generator_request_path<P>(&mut self, path: P) -> &mut Self
72+
where P: AsRef<Path>
73+
{
74+
self.raw_code_generator_request_path = Some(path.as_ref().to_path_buf());
75+
self
76+
}
77+
6878
/// Generates Rust code according to a `schema_capnp::code_generator_request` read from `inp`.
6979
pub fn run<T>(&mut self, inp: T) -> ::capnp::Result<()>
7080
where T: std::io::Read
@@ -119,6 +129,12 @@ impl CodeGenerationCommand {
119129
}
120130
}
121131
}
132+
133+
if let Some(raw_code_generator_request) = &self.raw_code_generator_request_path {
134+
let raw_code_generator_request_file = ::std::fs::File::create(&raw_code_generator_request).map_err(convert_io_err)?;
135+
serialize::write_message_segments(WriteWrapper{ inner: raw_code_generator_request_file }, &message.into_segments())?;
136+
}
137+
122138
Ok(())
123139
}
124140
}
@@ -2065,6 +2081,19 @@ impl <R> capnp::io::Read for ReadWrapper<R> where R: std::io::Read {
20652081
}
20662082
}
20672083

2084+
// The capnp crate defines a blanket impl of capnp::Write for R where R: std::io::Write,
2085+
// but we can't use that here because it lives behind the "std" feature flag.
2086+
struct WriteWrapper<W> where W: std::io::Write {
2087+
inner: W,
2088+
}
2089+
2090+
impl <W> capnp::io::Write for WriteWrapper<W> where W: std::io::Write {
2091+
fn write_all(&mut self, buf: &[u8]) -> ::capnp::Result<()> {
2092+
std::io::Write::write_all(&mut self.inner, buf).map_err(convert_io_err)?;
2093+
Ok(())
2094+
}
2095+
}
2096+
20682097
#[deprecated(since = "0.14.2", note = "Use CodeGenerationCommand::run() instead.")]
20692098
pub fn generate_code<T>(inp: T, out_dir: &::std::path::Path) -> ::capnp::Result<()>
20702099
where T: ::std::io::Read

capnpc/src/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub struct CompilerCommand {
105105
executable_path: Option<PathBuf>,
106106
output_path: Option<PathBuf>,
107107
default_parent_module: Vec<String>,
108+
raw_code_generator_request_path: Option<PathBuf>,
108109
}
109110

110111
impl CompilerCommand {
@@ -118,6 +119,7 @@ impl CompilerCommand {
118119
executable_path: None,
119120
output_path: None,
120121
default_parent_module: Vec::new(),
122+
raw_code_generator_request_path: None,
121123
}
122124
}
123125

@@ -200,6 +202,16 @@ impl CompilerCommand {
200202
self
201203
}
202204

205+
/// If set, the generator will also write a file containing the raw code generator request to the
206+
/// specified path.
207+
pub fn raw_code_generator_request_path<P>(&mut self, path: P) -> &mut CompilerCommand
208+
where
209+
P: AsRef<Path>,
210+
{
211+
self.raw_code_generator_request_path = Some(path.as_ref().to_path_buf());
212+
self
213+
}
214+
203215
/// Runs the command.
204216
/// Returns an error if `OUT_DIR` or a custom output directory was not set, or if `capnp compile` fails.
205217
pub fn run(&mut self) -> ::capnp::Result<()> {
@@ -263,6 +275,9 @@ impl CompilerCommand {
263275
code_generation_command
264276
.output_directory(output_path)
265277
.default_parent_module(self.default_parent_module.clone());
278+
if let Some(raw_code_generator_request_path) = &self.raw_code_generator_request_path {
279+
code_generation_command.raw_code_generator_request_path(raw_code_generator_request_path.clone());
280+
}
266281

267282
run_command(command, code_generation_command).map_err(|error| {
268283
::capnp::Error::failed(format!(

capnpc/test/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ capnpc = { path = "../" }
1515

1616
[dependencies]
1717
capnp = { path = "../../capnp" }
18+
capnpc = { path = "../" }

capnpc/test/build.rs

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ fn main() {
66
.file("schema/test-in-dir.capnp")
77
.file("schema-with-src-prefix/test-in-src-prefix-dir.capnp")
88
.src_prefix("schema-with-src-prefix")
9+
.raw_code_generator_request_path(
10+
std::env::var("OUT_DIR").expect("OUT_DIR env var is not set")
11+
+ "/raw_code_gen_request.bin",
12+
)
913
.run()
1014
.expect("compiling schema");
1115

capnpc/test/test.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1645,4 +1645,20 @@ mod tests {
16451645
let message_reader = TypedReader::<_, test_all_types::Owned>::new(reader);
16461646
::test_util::CheckTestMessage::check_test_message(message_reader.get().unwrap());
16471647
}
1648+
1649+
#[test]
1650+
fn test_raw_code_generator_request_path() {
1651+
use std::fs;
1652+
use capnp::serialize;
1653+
1654+
let raw_code_gen_request = fs::read(
1655+
std::env::var("OUT_DIR").expect("OUT_DIR env var is not set")
1656+
+ "/raw_code_gen_request.bin"
1657+
).expect("Failed to open raw code gen request file");
1658+
1659+
let reader = serialize::read_message(raw_code_gen_request.as_slice(), ReaderOptions::new()).unwrap();
1660+
let generator_context = capnpc::codegen::GeneratorContext::new(&reader).unwrap();
1661+
assert!(generator_context.node_map.len() > 0);
1662+
assert!(generator_context.scope_map.len() > 0);
1663+
}
16481664
}

0 commit comments

Comments
 (0)