diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69672ec1a..021039ad9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,3 +88,18 @@ jobs: - name: Run tests run: cargo test -p capnp -p capnpc -p capnp-futures -p capnp-rpc + fmt: + name: formatting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + profile: minimal + components: rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 000000000..1ac74e947 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +format_generated_files = false diff --git a/async-byte-channel/src/lib.rs b/async-byte-channel/src/lib.rs index bdad8866c..778a820d0 100644 --- a/async-byte-channel/src/lib.rs +++ b/async-byte-channel/src/lib.rs @@ -61,7 +61,9 @@ impl Drop for Receiver { pub fn channel() -> (Sender, Receiver) { let inner = Arc::new(Mutex::new(Inner::new())); - let sender = Sender { inner: inner.clone() }; + let sender = Sender { + inner: inner.clone(), + }; let receiver = Receiver { inner }; (sender, receiver) } @@ -70,8 +72,8 @@ impl AsyncRead for Receiver { fn poll_read( self: Pin<&mut Self>, cx: &mut futures::task::Context, - buf: &mut [u8]) -> futures::task::Poll> - { + buf: &mut [u8], + ) -> futures::task::Poll> { let mut inner = self.inner.lock().unwrap(); if inner.read_cursor == inner.write_cursor { if inner.write_end_closed { @@ -83,7 +85,8 @@ impl AsyncRead for Receiver { } else { assert!(inner.read_cursor < inner.write_cursor); let copy_len = std::cmp::min(buf.len(), inner.write_cursor - inner.read_cursor); - buf[0..copy_len].copy_from_slice(&inner.buffer[inner.read_cursor .. inner.read_cursor + copy_len]); + buf[0..copy_len] + .copy_from_slice(&inner.buffer[inner.read_cursor..inner.read_cursor + copy_len]); inner.read_cursor += copy_len; if let Some(write_waker) = inner.write_waker.take() { write_waker.wake(); @@ -97,11 +100,14 @@ impl AsyncWrite for Sender { fn poll_write( self: Pin<&mut Self>, cx: &mut futures::task::Context, - buf: &[u8]) -> futures::task::Poll> - { + buf: &[u8], + ) -> futures::task::Poll> { let mut inner = self.inner.lock().unwrap(); if inner.read_end_closed { - return Poll::Ready(Err(std::io::Error::new(std::io::ErrorKind::ConnectionAborted, "read end closed"))) + return Poll::Ready(Err(std::io::Error::new( + std::io::ErrorKind::ConnectionAborted, + "read end closed", + ))); } if inner.write_cursor == inner.buffer.len() { if inner.read_cursor == inner.buffer.len() { @@ -109,7 +115,7 @@ impl AsyncWrite for Sender { inner.read_cursor = 0; } else { inner.write_waker = Some(cx.waker().clone()); - return Poll::Pending + return Poll::Pending; } } @@ -127,17 +133,15 @@ impl AsyncWrite for Sender { fn poll_flush( self: Pin<&mut Self>, - _cx: &mut futures::task::Context) - -> Poll> - { + _cx: &mut futures::task::Context, + ) -> Poll> { Poll::Ready(Ok(())) } fn poll_close( self: Pin<&mut Self>, - _cx: &mut futures::task::Context) - -> Poll> - { + _cx: &mut futures::task::Context, + ) -> Poll> { let mut inner = self.inner.lock().unwrap(); inner.write_end_closed = true; if let Some(read_waker) = inner.read_waker.take() { @@ -149,20 +153,26 @@ impl AsyncWrite for Sender { #[cfg(test)] pub mod test { + use futures::task::LocalSpawnExt; use futures::{AsyncReadExt, AsyncWriteExt}; - use futures::task::{LocalSpawnExt}; #[test] fn basic() { let (mut sender, mut receiver) = crate::channel(); - let buf: Vec = vec![1,2,3,4,5].into_iter().cycle().take(20000).collect(); + let buf: Vec = vec![1, 2, 3, 4, 5] + .into_iter() + .cycle() + .take(20000) + .collect(); let mut pool = futures::executor::LocalPool::new(); let buf2 = buf.clone(); - pool.spawner().spawn_local(async move { - sender.write_all(&buf2).await.unwrap(); - () - }).unwrap(); + pool.spawner() + .spawn_local(async move { + sender.write_all(&buf2).await.unwrap(); + () + }) + .unwrap(); let mut buf3 = vec![]; pool.run_until(receiver.read_to_end(&mut buf3)).unwrap(); @@ -176,8 +186,7 @@ pub mod test { drop(receiver); let mut pool = futures::executor::LocalPool::new(); - let result = pool.run_until(sender.write_all(&[0,1,2])); + let result = pool.run_until(sender.write_all(&[0, 1, 2])); assert!(result.is_err()); } } - diff --git a/benchmark/benchmark.rs b/benchmark/benchmark.rs index 71952de3c..ea94fd985 100644 --- a/benchmark/benchmark.rs +++ b/benchmark/benchmark.rs @@ -19,25 +19,25 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use std::{io}; +use std::io; -use capnp::{message, serialize, serialize_packed}; use capnp::traits::Owned; +use capnp::{message, serialize, serialize_packed}; pub mod common; pub mod carsales_capnp { - include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs")); } pub mod carsales; pub mod catrank_capnp { - include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs")); } pub mod catrank; pub mod eval_capnp { - include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs")); } pub mod eval; @@ -47,37 +47,65 @@ trait TestCase { type Response: Owned; type Expectation; - fn setup_request(&self, rnd: &mut crate::common::FastRand, b: ::Builder<'_>) -> Self::Expectation; - fn handle_request(&self, r: ::Reader<'_>, b: ::Builder<'_>) - -> ::capnp::Result<()>; - fn check_response(&self, r: ::Reader<'_>, e: Self::Expectation) -> ::capnp::Result<()>; + fn setup_request( + &self, + rnd: &mut crate::common::FastRand, + b: ::Builder<'_>, + ) -> Self::Expectation; + fn handle_request( + &self, + r: ::Reader<'_>, + b: ::Builder<'_>, + ) -> ::capnp::Result<()>; + fn check_response( + &self, + r: ::Reader<'_>, + e: Self::Expectation, + ) -> ::capnp::Result<()>; } trait Serialize { fn read_message( &self, read: &mut R, - options: message::ReaderOptions) - -> ::capnp::Result> - where R: io::BufRead; + options: message::ReaderOptions, + ) -> ::capnp::Result> + where + R: io::BufRead; - fn write_message(&self, write: &mut W, message: &message::Builder) -> ::capnp::Result<()> - where W: io::Write, A: message::Allocator; + fn write_message( + &self, + write: &mut W, + message: &message::Builder, + ) -> ::capnp::Result<()> + where + W: io::Write, + A: message::Allocator; } struct NoCompression; impl Serialize for NoCompression { - fn read_message(&self, read: &mut R, - options: message::ReaderOptions) - -> ::capnp::Result> - where R: io::BufRead + fn read_message( + &self, + read: &mut R, + options: message::ReaderOptions, + ) -> ::capnp::Result> + where + R: io::BufRead, { serialize::read_message(read, options) } - fn write_message(&self, write: &mut W, message: &message::Builder) -> ::capnp::Result<()> - where W: io::Write, A: message::Allocator { + fn write_message( + &self, + write: &mut W, + message: &message::Builder, + ) -> ::capnp::Result<()> + where + W: io::Write, + A: message::Allocator, + { serialize::write_message(write, message).map_err(|e| e.into()) } } @@ -85,16 +113,26 @@ impl Serialize for NoCompression { struct Packed; impl Serialize for Packed { - fn read_message(&self, read: &mut R, - options: message::ReaderOptions) - -> ::capnp::Result> - where R: io::BufRead + fn read_message( + &self, + read: &mut R, + options: message::ReaderOptions, + ) -> ::capnp::Result> + where + R: io::BufRead, { serialize_packed::read_message(read, options) } - fn write_message(&self, write: &mut W, message: &message::Builder) -> ::capnp::Result<()> - where W: io::Write, A: message::Allocator { + fn write_message( + &self, + write: &mut W, + message: &message::Builder, + ) -> ::capnp::Result<()> + where + W: io::Write, + A: message::Allocator, + { serialize_packed::write_message(write, message).map_err(|e| e.into()) } } @@ -110,7 +148,7 @@ const SCRATCH_SIZE: usize = 128 * 1024; #[derive(Clone, Copy)] pub struct NoScratch; -impl <'a> Scratch<'a> for NoScratch { +impl<'a> Scratch<'a> for NoScratch { type Allocator = message::HeapAllocator; fn get_allocators(&'a mut self) -> (Self::Allocator, Self::Allocator) { @@ -132,18 +170,25 @@ impl UseScratch { } } -impl <'a> Scratch<'a> for UseScratch { +impl<'a> Scratch<'a> for UseScratch { type Allocator = message::ScratchSpaceHeapAllocator<'a>; fn get_allocators(&'a mut self) -> (Self::Allocator, Self::Allocator) { - let UseScratch {ref mut buffer1, ref mut buffer2 } = self; - (message::ScratchSpaceHeapAllocator::new(capnp::Word::words_to_bytes_mut(buffer1)), - message::ScratchSpaceHeapAllocator::new(capnp::Word::words_to_bytes_mut(buffer2))) + let UseScratch { + ref mut buffer1, + ref mut buffer2, + } = self; + ( + message::ScratchSpaceHeapAllocator::new(capnp::Word::words_to_bytes_mut(buffer1)), + message::ScratchSpaceHeapAllocator::new(capnp::Word::words_to_bytes_mut(buffer2)), + ) } } fn pass_by_object(testcase: T, mut reuse: S, iters: u64) -> ::capnp::Result<()> - where S: for<'a> Scratch<'a>, T: TestCase, +where + S: for<'a> Scratch<'a>, + T: TestCase, { let mut rng = common::FastRand::new(); let (mut allocator_req, mut allocator_res) = reuse.get_allocators(); @@ -151,23 +196,25 @@ fn pass_by_object(testcase: T, mut reuse: S, iters: u64) -> ::capnp::Resul let mut message_req = message::Builder::new(&mut allocator_req); let mut message_res = message::Builder::new(&mut allocator_res); - let expected = testcase.setup_request( - &mut rng, - message_req.init_root()); + let expected = testcase.setup_request(&mut rng, message_req.init_root()); - testcase.handle_request( - message_req.get_root_as_reader()?, - message_res.init_root())?; + testcase.handle_request(message_req.get_root_as_reader()?, message_res.init_root())?; - testcase.check_response( - message_res.get_root_as_reader()?, - expected)?; + testcase.check_response(message_res.get_root_as_reader()?, expected)?; } Ok(()) } -fn pass_by_bytes(testcase: T, mut reuse: S, compression: C, iters: u64) -> ::capnp::Result<()> - where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase, +fn pass_by_bytes( + testcase: T, + mut reuse: S, + compression: C, + iters: u64, +) -> ::capnp::Result<()> +where + C: Serialize, + S: for<'a> Scratch<'a>, + T: TestCase, { let mut request_bytes = vec![0u8; SCRATCH_SIZE * 8]; let mut response_bytes = vec![0u8; SCRATCH_SIZE * 8]; @@ -191,9 +238,8 @@ fn pass_by_bytes(testcase: T, mut reuse: S, compression: C, iters: u64) } let mut request_bytes1: &[u8] = &request_bytes; - let message_reader = compression.read_message( - &mut request_bytes1, - Default::default())?; + let message_reader = + compression.read_message(&mut request_bytes1, Default::default())?; let request_reader = message_reader.get_root()?; testcase.handle_request(request_reader, response)?; @@ -205,9 +251,7 @@ fn pass_by_bytes(testcase: T, mut reuse: S, compression: C, iters: u64) } let mut response_bytes1: &[u8] = &response_bytes; - let message_reader = compression.read_message( - &mut response_bytes1, - Default::default())?; + let message_reader = compression.read_message(&mut response_bytes1, Default::default())?; let response_reader = message_reader.get_root()?; testcase.check_response(response_reader, expected)?; @@ -215,9 +259,20 @@ fn pass_by_bytes(testcase: T, mut reuse: S, compression: C, iters: u64) Ok(()) } -fn server(testcase: T, mut reuse: S, compression: C, iters: u64, mut input: R, mut output: W) - -> ::capnp::Result<()> - where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase, R: io::Read, W: io::Write, +fn server( + testcase: T, + mut reuse: S, + compression: C, + iters: u64, + mut input: R, + mut output: W, +) -> ::capnp::Result<()> +where + C: Serialize, + S: for<'a> Scratch<'a>, + T: TestCase, + R: io::Read, + W: io::Write, { let mut out_buffered = io::BufWriter::new(&mut output); let mut in_buffered = io::BufReader::new(&mut input); @@ -228,9 +283,8 @@ fn server(testcase: T, mut reuse: S, compression: C, iters: u64, { let response = message_res.init_root(); - let message_reader = compression.read_message( - &mut in_buffered, - capnp::message::DEFAULT_READER_OPTIONS)?; + let message_reader = compression + .read_message(&mut in_buffered, capnp::message::DEFAULT_READER_OPTIONS)?; let request_reader = message_reader.get_root()?; testcase.handle_request(request_reader, response)?; } @@ -241,9 +295,16 @@ fn server(testcase: T, mut reuse: S, compression: C, iters: u64, Ok(()) } -fn sync_client(testcase: T, mut reuse: S, compression: C, iters: u64) - -> ::capnp::Result<()> - where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase, +fn sync_client( + testcase: T, + mut reuse: S, + compression: C, + iters: u64, +) -> ::capnp::Result<()> +where + C: Serialize, + S: for<'a> Scratch<'a>, + T: TestCase, { let mut out_stream: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(1) }; let mut in_stream: ::std::fs::File = unsafe { ::std::os::unix::io::FromRawFd::from_raw_fd(0) }; @@ -262,9 +323,7 @@ fn sync_client(testcase: T, mut reuse: S, compression: C, iters: u64) compression.write_message(&mut out_buffered, &mut message_req)?; out_buffered.flush()?; - let message_reader = compression.read_message( - &mut in_buffered, - Default::default())?; + let message_reader = compression.read_message(&mut in_buffered, Default::default())?; let response_reader = message_reader.get_root()?; testcase.check_response(response_reader, expected)?; } @@ -272,9 +331,12 @@ fn sync_client(testcase: T, mut reuse: S, compression: C, iters: u64) } fn pass_by_pipe(testcase: T, reuse: S, compression: C, iters: u64) -> ::capnp::Result<()> - where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase, +where + C: Serialize, + S: for<'a> Scratch<'a>, + T: TestCase, { - use std::{process, env}; + use std::{env, process}; let mut args: Vec = env::args().collect(); args[2] = "client".to_string(); @@ -288,7 +350,14 @@ fn pass_by_pipe(testcase: T, reuse: S, compression: C, iters: u64) -> : Ok(ref mut p) => { let child_std_out = p.stdout.take().unwrap(); let child_std_in = p.stdin.take().unwrap(); - server(testcase, reuse, compression, iters, child_std_out, child_std_in)?; + server( + testcase, + reuse, + compression, + iters, + child_std_out, + child_std_in, + )?; println!("{}", p.wait().unwrap()); Ok(()) } @@ -320,8 +389,17 @@ impl Mode { } } -fn do_testcase(testcase: T, mode: Mode, reuse: S, compression: C, iters: u64) -> ::capnp::Result<()> - where C: Serialize, S: for<'a> Scratch<'a>, T: TestCase, +fn do_testcase( + testcase: T, + mode: Mode, + reuse: S, + compression: C, + iters: u64, +) -> ::capnp::Result<()> +where + C: Serialize, + S: for<'a> Scratch<'a>, + T: TestCase, { match mode { Mode::Object => pass_by_object(testcase, reuse, iters), @@ -336,38 +414,65 @@ fn do_testcase(testcase: T, mode: Mode, reuse: S, compression: C, iters } } -fn do_testcase1(case: &str, mode: Mode, scratch: S, compression: C, iters: u64) -> ::capnp::Result<()> - where C: Serialize, S: for<'a> Scratch<'a>, +fn do_testcase1( + case: &str, + mode: Mode, + scratch: S, + compression: C, + iters: u64, +) -> ::capnp::Result<()> +where + C: Serialize, + S: for<'a> Scratch<'a>, { match case { "carsales" => do_testcase(carsales::CarSales, mode, scratch, compression, iters), "catrank" => do_testcase(catrank::CatRank, mode, scratch, compression, iters), "eval" => do_testcase(eval::Eval, mode, scratch, compression, iters), - s => Err(::capnp::Error::failed(format!("unrecognized test case: {}", s))), + s => Err(::capnp::Error::failed(format!( + "unrecognized test case: {}", + s + ))), } } -fn do_testcase2(case: &str, mode: Mode, scratch: &str, compression: C, iters: u64) -> ::capnp::Result<()> - where C: Serialize, +fn do_testcase2( + case: &str, + mode: Mode, + scratch: &str, + compression: C, + iters: u64, +) -> ::capnp::Result<()> +where + C: Serialize, { match scratch { "no-reuse" => do_testcase1(case, mode, NoScratch, compression, iters), "reuse" => do_testcase1(case, mode, UseScratch::new(), compression, iters), - s => Err(::capnp::Error::failed(format!("unrecognized reuse option: {}", s))), + s => Err(::capnp::Error::failed(format!( + "unrecognized reuse option: {}", + s + ))), } } fn try_main() -> ::capnp::Result<()> { let args: Vec = ::std::env::args().collect(); - assert!(args.len() == 6, - "USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT", - args[0]); + assert!( + args.len() == 6, + "USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT", + args[0] + ); let iters = match args[5].parse::() { Ok(n) => n, - Err(_) => - return Err(::capnp::Error::failed(format!("Could not parse a u64 from: {}", args[5]))), + Err(_) => { + return Err(::capnp::Error::failed(format!( + "Could not parse a u64 from: {}", + args[5] + ))) + } }; let mode = Mode::parse(&*args[2])?; @@ -375,7 +480,10 @@ fn try_main() -> ::capnp::Result<()> { match &*args[4] { "none" => do_testcase2(&*args[1], mode, &*args[3], NoCompression, iters), "packed" => do_testcase2(&*args[1], mode, &*args[3], Packed, iters), - s => Err(::capnp::Error::failed(format!("unrecognized compression: {}", s))), + s => Err(::capnp::Error::failed(format!( + "unrecognized compression: {}", + s + ))), } } diff --git a/benchmark/carsales.rs b/benchmark/carsales.rs index 83636954c..fc89a4038 100644 --- a/benchmark/carsales.rs +++ b/benchmark/carsales.rs @@ -19,8 +19,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +use crate::carsales_capnp::{car, parking_lot, total_value, Color}; use crate::common::*; -use crate::carsales_capnp::{parking_lot, total_value, Color, car}; trait CarValue { fn car_value(self) -> ::capnp::Result; @@ -78,14 +78,17 @@ macro_rules! car_value_impl( car_value_impl!(Reader); car_value_impl!(Builder); -const MAKES : [&'static str; 5] = ["Toyota", "GM", "Ford", "Honda", "Tesla"]; -const MODELS : [&'static str; 6] = ["Camry", "Prius", "Volt", "Accord", "Leaf", "Model S"]; +const MAKES: [&'static str; 5] = ["Toyota", "GM", "Ford", "Honda", "Tesla"]; +const MODELS: [&'static str; 6] = ["Camry", "Prius", "Volt", "Accord", "Leaf", "Model S"]; pub fn random_car(rng: &mut FastRand, mut car: car::Builder) { car.set_make(MAKES[rng.next_less_than(MAKES.len() as u32) as usize]); car.set_model(MODELS[rng.next_less_than(MODELS.len() as u32) as usize]); - car.set_color(::capnp::traits::FromU16::from_u16(rng.next_less_than(Color::Silver as u32 + 1) as u16).unwrap()); + car.set_color( + ::capnp::traits::FromU16::from_u16(rng.next_less_than(Color::Silver as u32 + 1) as u16) + .unwrap(), + ); car.set_seats(2 + rng.next_less_than(6) as u8); car.set_doors(2 + rng.next_less_than(3) as u8); @@ -136,7 +139,7 @@ impl crate::TestCase for CarSales { fn setup_request(&self, rng: &mut FastRand, request: parking_lot::Builder) -> u64 { let mut result = 0; let mut cars = request.init_cars(rng.next_less_than(200)); - for ii in 0.. cars.len() { + for ii in 0..cars.len() { let mut car = cars.reborrow().get(ii); random_car(rng, car.reborrow()); result += car.car_value().unwrap(); @@ -145,9 +148,11 @@ impl crate::TestCase for CarSales { result } - fn handle_request(&self, request: parking_lot::Reader, mut response: total_value::Builder) - -> ::capnp::Result<()> - { + fn handle_request( + &self, + request: parking_lot::Reader, + mut response: total_value::Builder, + ) -> ::capnp::Result<()> { let mut result = 0; for car in request.get_cars()?.iter() { result += car.car_value()?; @@ -160,8 +165,11 @@ impl crate::TestCase for CarSales { if response.get_amount() == expected { Ok(()) } else { - Err(::capnp::Error::failed( - format!("check_response() expected {} but got {}", expected, response.get_amount()))) + Err(::capnp::Error::failed(format!( + "check_response() expected {} but got {}", + expected, + response.get_amount() + ))) } } } diff --git a/benchmark/catrank.rs b/benchmark/catrank.rs index e418765c2..d7d81225d 100644 --- a/benchmark/catrank.rs +++ b/benchmark/catrank.rs @@ -19,13 +19,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use crate::common::*; use crate::catrank_capnp::*; +use crate::common::*; #[derive(Clone, Copy)] pub struct ScoredResult<'a> { score: f64, - result: search_result::Reader<'a> + result: search_result::Reader<'a>, } const URL_PREFIX: &'static str = "http://example.com"; @@ -50,7 +50,9 @@ impl crate::TestCase for CatRank { let url_prefix_length = URL_PREFIX.as_bytes().len(); { - let mut url = result.reborrow().init_url(url_size + url_prefix_length as u32); + let mut url = result + .reborrow() + .init_url(url_size + url_prefix_length as u32); url.push_str(URL_PREFIX); for _ in 0..url_size { @@ -70,8 +72,12 @@ impl crate::TestCase for CatRank { for _ in 0..prefix { snippet.push_str(WORDS[rng.next_less_than(WORDS.len() as u32) as usize]); } - if is_cat { snippet.push_str("cat ") } - if is_dog { snippet.push_str("dog ") } + if is_cat { + snippet.push_str("cat ") + } + if is_dog { + snippet.push_str("dog ") + } let suffix = rng.next_less_than(20) as usize; for _ in 0..suffix { @@ -84,9 +90,11 @@ impl crate::TestCase for CatRank { good_count } - fn handle_request(&self, request: search_result_list::Reader, - response: search_result_list::Builder) -> ::capnp::Result<()> - { + fn handle_request( + &self, + request: search_result_list::Reader, + response: search_result_list::Builder, + ) -> ::capnp::Result<()> { let mut scored_results: Vec = Vec::new(); let results = request.get_results()?; @@ -100,12 +108,20 @@ impl crate::TestCase for CatRank { if snippet.contains(" dog ") { score /= 10000.0; } - scored_results.push(ScoredResult {score : score, result : result}); + scored_results.push(ScoredResult { + score: score, + result: result, + }); } // sort in decreasing order - scored_results.sort_by(|v1, v2| { if v1.score < v2.score { ::std::cmp::Ordering::Greater } - else { ::std::cmp::Ordering::Less } }); + scored_results.sort_by(|v1, v2| { + if v1.score < v2.score { + ::std::cmp::Ordering::Greater + } else { + ::std::cmp::Ordering::Less + } + }); let mut list = response.init_results(scored_results.len() as u32); for i in 0..list.len() { @@ -119,10 +135,12 @@ impl crate::TestCase for CatRank { Ok(()) } - fn check_response(&self, response: search_result_list::Reader, expected_good_count: i32) - -> ::capnp::Result<()> - { - let mut good_count : i32 = 0; + fn check_response( + &self, + response: search_result_list::Reader, + expected_good_count: i32, + ) -> ::capnp::Result<()> { + let mut good_count: i32 = 0; let results = response.get_results()?; for result in results.iter() { if result.get_score() > 1001.0 { @@ -135,8 +153,10 @@ impl crate::TestCase for CatRank { if good_count == expected_good_count { Ok(()) } else { - Err(::capnp::Error::failed( - format!("check_response() expected {} but got {}", expected_good_count, good_count))) + Err(::capnp::Error::failed(format!( + "check_response() expected {} but got {}", + expected_good_count, good_count + ))) } } } diff --git a/benchmark/common.rs b/benchmark/common.rs index b1eaeeac0..58ea8fb4d 100644 --- a/benchmark/common.rs +++ b/benchmark/common.rs @@ -32,10 +32,10 @@ pub struct FastRand { impl FastRand { pub fn new() -> FastRand { FastRand { - x : 0x1d2acd47, - y : 0x58ca3e14, - z : 0xf563f232, - w : 0x0bc76199, + x: 0x1d2acd47, + y: 0x58ca3e14, + z: 0xf563f232, + w: 0x0bc76199, } } @@ -50,7 +50,7 @@ impl FastRand { } #[inline] - pub fn next_less_than(&mut self, range : u32) -> u32 { + pub fn next_less_than(&mut self, range: u32) -> u32 { self.next_u32() % range } @@ -60,15 +60,17 @@ impl FastRand { } #[inline] - pub fn next_double(&mut self, range : f64) -> f64 { + pub fn next_double(&mut self, range: f64) -> f64 { use std::u32; self.next_u32() as f64 * range / (u32::MAX as f64) } } #[inline] -pub fn div(a : i32, b: i32) -> i32 { - if b == 0 { return i32::MAX } +pub fn div(a: i32, b: i32) -> i32 { + if b == 0 { + return i32::MAX; + } if a == i32::MIN && b == -1 { return i32::MAX; } @@ -76,16 +78,17 @@ pub fn div(a : i32, b: i32) -> i32 { } #[inline] -pub fn modulus(a : i32, b: i32) -> i32 { - if b == 0 { return i32::MAX } +pub fn modulus(a: i32, b: i32) -> i32 { + if b == 0 { + return i32::MAX; + } if a == i32::MIN && b == -1 { return i32::MAX; } return a % b; } -pub const WORDS : [&'static str; 13] = [ +pub const WORDS: [&'static str; 13] = [ "foo ", "bar ", "baz ", "qux ", "quux ", "corge ", "grault ", "garply ", "waldo ", "fred ", - "plugh ", "xyzzy ", "thud "]; - - + "plugh ", "xyzzy ", "thud ", +]; diff --git a/benchmark/eval.rs b/benchmark/eval.rs index 96e6c7b69..aa7d383ab 100644 --- a/benchmark/eval.rs +++ b/benchmark/eval.rs @@ -20,13 +20,12 @@ // THE SOFTWARE. use crate::common::*; -use crate::eval_capnp::{expression, evaluation_result, Operation}; +use crate::eval_capnp::{evaluation_result, expression, Operation}; -fn make_expression(rng: &mut FastRand, mut exp: expression::Builder, depth : u32) -> i32 { +fn make_expression(rng: &mut FastRand, mut exp: expression::Builder, depth: u32) -> i32 { exp.set_op(::capnp::traits::FromU16::from_u16(rng.next_less_than( Operation::Modulus as u32 + 1) as u16).unwrap()); - let left : i32 = - if rng.next_less_than(8) < depth { + let left: i32 = if rng.next_less_than(8) < depth { let tmp = (rng.next_less_than(128) + 1) as i32; exp.reborrow().get_left().set_value(tmp); tmp @@ -34,8 +33,7 @@ fn make_expression(rng: &mut FastRand, mut exp: expression::Builder, depth : u32 make_expression(rng, exp.reborrow().get_left().init_expression(), depth + 1) }; - let right : i32 = - if rng.next_less_than(8) < depth { + let right: i32 = if rng.next_less_than(8) < depth { let tmp = (rng.next_less_than(128) + 1) as i32; exp.reborrow().get_right().set_value(tmp); tmp @@ -44,11 +42,11 @@ fn make_expression(rng: &mut FastRand, mut exp: expression::Builder, depth : u32 }; match exp.get_op().unwrap() { - Operation::Add => { return left + right } - Operation::Subtract => { return left - right } - Operation::Multiply => { return left * right } - Operation::Divide => { return div(left, right) } - Operation::Modulus => { return modulus(left, right) } + Operation::Add => return left + right, + Operation::Subtract => return left - right, + Operation::Multiply => return left * right, + Operation::Divide => return div(left, right), + Operation::Modulus => return modulus(left, right), } } @@ -82,19 +80,28 @@ impl crate::TestCase for Eval { make_expression(rng, request, 0) } - fn handle_request(&self, request: expression::Reader, mut response: evaluation_result::Builder) - -> ::capnp::Result<()> - { + fn handle_request( + &self, + request: expression::Reader, + mut response: evaluation_result::Builder, + ) -> ::capnp::Result<()> { response.set_value(evaluate_expression(request)?); Ok(()) } - fn check_response(&self, response: evaluation_result::Reader, expected : i32) -> ::capnp::Result<()> { + fn check_response( + &self, + response: evaluation_result::Reader, + expected: i32, + ) -> ::capnp::Result<()> { if response.get_value() == expected { Ok(()) } else { - Err(::capnp::Error::failed( - format!("check_response() expected {} but got {}", expected, response.get_value()))) + Err(::capnp::Error::failed(format!( + "check_response() expected {} but got {}", + expected, + response.get_value() + ))) } } } diff --git a/benchmark/run_all.rs b/benchmark/run_all.rs index b60bf8ad4..ffdedea3b 100644 --- a/benchmark/run_all.rs +++ b/benchmark/run_all.rs @@ -21,9 +21,17 @@ use std::{env, process, time}; -fn run_one(executable: &str, case: &str, mode: &str, scratch: &str, compression: &str, iteration_count: u64) { +fn run_one( + executable: &str, + case: &str, + mode: &str, + scratch: &str, + compression: &str, + iteration_count: u64, +) { let mut command = process::Command::new(executable); - command.arg(case) + command + .arg(case) .arg(mode) .arg(scratch) .arg(compression) @@ -49,7 +57,14 @@ fn run_case(executable: &str, case: &str, scratch_options: &[&str], iteration_co for mode in &["bytes", "pipe"] { for compression in &["none", "packed"] { for scratch in scratch_options { - run_one(executable, case, mode, scratch, compression, iteration_count); + run_one( + executable, + case, + mode, + scratch, + compression, + iteration_count, + ); } } } @@ -58,12 +73,18 @@ fn run_case(executable: &str, case: &str, scratch_options: &[&str], iteration_co fn try_main() -> ::capnp::Result<()> { let args: Vec = env::args().collect(); - assert!(args.len() == 2 || args.len() == 5, - "USAGE: {} BENCHMARK_EXECUTABLE [CARSALES_ITERS CATRANK_ITERS EVAL_ITERS]", - args[0]); + assert!( + args.len() == 2 || args.len() == 5, + "USAGE: {} BENCHMARK_EXECUTABLE [CARSALES_ITERS CATRANK_ITERS EVAL_ITERS]", + args[0] + ); let (carsales_iters, catrank_iters, eval_iters) = if args.len() > 2 { - (args[2].parse::().unwrap(), args[3].parse::().unwrap(), args[4].parse::().unwrap()) + ( + args[2].parse::().unwrap(), + args[3].parse::().unwrap(), + args[4].parse::().unwrap(), + ) } else { (10000, 1000, 200000) }; @@ -71,7 +92,12 @@ fn try_main() -> ::capnp::Result<()> { let executable = &*args[1]; println!("running carsales with {} iterations", carsales_iters); - run_case(executable, "carsales", &["reuse", "no-reuse"], carsales_iters); + run_case( + executable, + "carsales", + &["reuse", "no-reuse"], + carsales_iters, + ); println!("running catrank with {} iterations", catrank_iters); run_case(executable, "catrank", &["no-reuse"], catrank_iters); diff --git a/capnp-futures/src/lib.rs b/capnp-futures/src/lib.rs index 9dafd3948..40caac42c 100644 --- a/capnp-futures/src/lib.rs +++ b/capnp-futures/src/lib.rs @@ -21,7 +21,7 @@ pub use read_stream::ReadStream; pub use write_queue::{write_queue, Sender}; +mod read_stream; pub mod serialize; pub mod serialize_packed; -mod read_stream; mod write_queue; diff --git a/capnp-futures/src/read_stream.rs b/capnp-futures/src/read_stream.rs index aeeb0b69c..1d7e6f669 100644 --- a/capnp-futures/src/read_stream.rs +++ b/capnp-futures/src/read_stream.rs @@ -18,33 +18,50 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use std::pin::Pin; -use std::task::{Context, Poll}; use futures::future::Future; use futures::stream::Stream; -use futures::{AsyncRead}; +use futures::AsyncRead; +use std::pin::Pin; +use std::task::{Context, Poll}; -use capnp::{Error, message}; +use capnp::{message, Error}; -async fn read_next_message(mut reader: R, options: message::ReaderOptions) - -> Result<(R, Option>), Error> - where R: AsyncRead + Unpin +async fn read_next_message( + mut reader: R, + options: message::ReaderOptions, +) -> Result<(R, Option>), Error> +where + R: AsyncRead + Unpin, { let m = crate::serialize::try_read_message(&mut reader, options).await?; Ok((reader, m)) } #[must_use = "streams do nothing unless polled"] -pub struct ReadStream<'a, R> where R: AsyncRead + Unpin { +pub struct ReadStream<'a, R> +where + R: AsyncRead + Unpin, +{ options: message::ReaderOptions, - read: Pin>), Error>> + 'a >>, + read: Pin< + Box< + dyn Future< + Output = Result< + (R, Option>), + Error, + >, + > + 'a, + >, + >, } -impl <'a, R> Unpin for ReadStream<'a, R> where R: AsyncRead + Unpin {} +impl<'a, R> Unpin for ReadStream<'a, R> where R: AsyncRead + Unpin {} -impl <'a, R> ReadStream<'a, R> where R: AsyncRead + Unpin + 'a { - pub fn new(reader: R, options: message::ReaderOptions) -> Self - { +impl<'a, R> ReadStream<'a, R> +where + R: AsyncRead + Unpin + 'a, +{ + pub fn new(reader: R, options: message::ReaderOptions) -> Self { ReadStream { read: Box::pin(read_next_message(reader, options)), options, @@ -52,7 +69,10 @@ impl <'a, R> ReadStream<'a, R> where R: AsyncRead + Unpin + 'a { } } -impl <'a, R> Stream for ReadStream<'a, R> where R: AsyncRead + Unpin + 'a { +impl<'a, R> Stream for ReadStream<'a, R> +where + R: AsyncRead + Unpin + 'a, +{ type Item = Result, Error>; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { diff --git a/capnp-futures/src/serialize.rs b/capnp-futures/src/serialize.rs index d7723f7f6..27e05e89c 100644 --- a/capnp-futures/src/serialize.rs +++ b/capnp-futures/src/serialize.rs @@ -23,20 +23,22 @@ use std::convert::TryInto; -use capnp::{message, Error, Result, OutputSegments}; use capnp::serialize::{OwnedSegments, SegmentLengthsBuilder}; +use capnp::{message, Error, OutputSegments, Result}; use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; - /// Asynchronously reads a message from `reader`. -pub async fn read_message(reader: R, options: message::ReaderOptions) - -> Result> -where R: AsyncRead + Unpin +pub async fn read_message( + reader: R, + options: message::ReaderOptions, +) -> Result> +where + R: AsyncRead + Unpin, { match try_read_message(reader, options).await? { Some(s) => Ok(s), - None => Err(Error::failed("Premature end of file".to_string())) + None => Err(Error::failed("Premature end of file".to_string())), } } @@ -44,26 +46,39 @@ where R: AsyncRead + Unpin /// has zero bytes left (i.e. is at end-of-file). To read a stream /// containing an unknown number of messages, you could call this function /// repeatedly until it returns `None`. -pub async fn try_read_message(mut reader: R, options: message::ReaderOptions) -> Result>> - where R: AsyncRead + Unpin +pub async fn try_read_message( + mut reader: R, + options: message::ReaderOptions, +) -> Result>> +where + R: AsyncRead + Unpin, { let segment_lengths_builder = match read_segment_table(&mut reader, options).await? { Some(s) => s, None => return Ok(None), }; - Ok(Some(read_segments(reader, segment_lengths_builder.into_owned_segments(), options).await?)) + Ok(Some( + read_segments( + reader, + segment_lengths_builder.into_owned_segments(), + options, + ) + .await?, + )) } -async fn read_segment_table(mut reader: R, - options: message::ReaderOptions) - -> Result> - where R: AsyncRead + Unpin +async fn read_segment_table( + mut reader: R, + options: message::ReaderOptions, +) -> Result> +where + R: AsyncRead + Unpin, { let mut buf: [u8; 8] = [0; 8]; { let n = reader.read(&mut buf[..]).await?; if n == 0 { - return Ok(None) + return Ok(None); } else if n < 8 { reader.read_exact(&mut buf[n..]).await?; } @@ -86,7 +101,8 @@ async fn read_segment_table(mut reader: R, reader.read_exact(&mut segment_sizes[..]).await?; for idx in 0..(segment_count - 1) { let segment_len = - u32::from_le_bytes(segment_sizes[(idx * 4)..(idx + 1) * 4].try_into().unwrap()) as usize; + u32::from_le_bytes(segment_sizes[(idx * 4)..(idx + 1) * 4].try_into().unwrap()) + as usize; segment_lengths_builder.push_segment(segment_len); } } @@ -96,10 +112,12 @@ async fn read_segment_table(mut reader: R, // traversal limit. Without this check, a malicious client could transmit a very large segment // size to make the receiver allocate excessive space and possibly crash. if let Some(traversal_limit_in_words) = options.traversal_limit_in_words { - if segment_lengths_builder.total_words() > traversal_limit_in_words { - return Err(Error::failed( - format!("Message has {} words, which is too large. To increase the limit on the \ - receiving end, see capnp::message::ReaderOptions.", segment_lengths_builder.total_words()))) + if segment_lengths_builder.total_words() > traversal_limit_in_words { + return Err(Error::failed(format!( + "Message has {} words, which is too large. To increase the limit on the \ + receiving end, see capnp::message::ReaderOptions.", + segment_lengths_builder.total_words() + ))); } } @@ -107,11 +125,13 @@ async fn read_segment_table(mut reader: R, } /// Reads segments from `read`. -async fn read_segments(mut read: R, - mut owned_segments: OwnedSegments, - options: message::ReaderOptions) - -> Result> - where R: AsyncRead + Unpin +async fn read_segments( + mut read: R, + mut owned_segments: OwnedSegments, + options: message::ReaderOptions, +) -> Result> +where + R: AsyncRead + Unpin, { read.read_exact(&mut owned_segments[..]).await?; Ok(message::Reader::new(owned_segments, options)) @@ -124,13 +144,18 @@ async fn read_segments(mut read: R, /// /// Returns the segment count and first segment length, or a state if the /// read would block. -fn parse_segment_table_first(buf: &[u8]) -> Result<(usize, usize)> -{ +fn parse_segment_table_first(buf: &[u8]) -> Result<(usize, usize)> { let segment_count = u32::from_le_bytes(buf[0..4].try_into().unwrap()).wrapping_add(1); if segment_count >= 512 { - return Err(Error::failed(format!("Too many segments: {}", segment_count))) + return Err(Error::failed(format!( + "Too many segments: {}", + segment_count + ))); } else if segment_count == 0 { - return Err(Error::failed(format!("Too few segments: {}", segment_count))) + return Err(Error::failed(format!( + "Too few segments: {}", + segment_count + ))); } let first_segment_len = u32::from_le_bytes(buf[4..8].try_into().unwrap()); @@ -142,14 +167,19 @@ pub trait AsOutputSegments { fn as_output_segments(&self) -> OutputSegments; } - -impl <'a, M> AsOutputSegments for &'a M where M: AsOutputSegments { +impl<'a, M> AsOutputSegments for &'a M +where + M: AsOutputSegments, +{ fn as_output_segments(&self) -> OutputSegments { (*self).as_output_segments() } } -impl AsOutputSegments for message::Builder where A: message::Allocator { +impl AsOutputSegments for message::Builder +where + A: message::Allocator, +{ fn as_output_segments(&self) -> OutputSegments { self.get_segments_for_output() } @@ -161,15 +191,20 @@ impl AsOutputSegments for message::Builder where A: message::Allocator { } }*/ -impl AsOutputSegments for ::std::rc::Rc> where A: message::Allocator { +impl AsOutputSegments for ::std::rc::Rc> +where + A: message::Allocator, +{ fn as_output_segments(&self) -> OutputSegments { self.get_segments_for_output() } } /// Writes the provided message to `writer`. Does not call `flush()`. -pub async fn write_message(mut writer: W, message: M) -> Result<()> - where W: AsyncWrite + Unpin, M: AsOutputSegments +pub async fn write_message(mut writer: W, message: M) -> Result<()> +where + W: AsyncWrite + Unpin, + M: AsOutputSegments, { let segments = message.as_output_segments(); write_segment_table(&mut writer, &segments[..]).await?; @@ -178,7 +213,8 @@ pub async fn write_message(mut writer: W, message: M) -> Result<()> } async fn write_segment_table(mut write: W, segments: &[&[u8]]) -> ::std::io::Result<()> - where W: AsyncWrite + Unpin +where + W: AsyncWrite + Unpin, { let mut buf: [u8; 8] = [0; 8]; let segment_count = segments.len(); @@ -191,21 +227,25 @@ async fn write_segment_table(mut write: W, segments: &[&[u8]]) -> ::std::io:: if segment_count > 1 { if segment_count < 4 { for idx in 1..segment_count { - buf[(idx - 1) * 4..idx * 4].copy_from_slice( - &((segments[idx].len() / 8) as u32).to_le_bytes()); + buf[(idx - 1) * 4..idx * 4] + .copy_from_slice(&((segments[idx].len() / 8) as u32).to_le_bytes()); } if segment_count == 2 { - for idx in 4..8 { buf[idx] = 0 } + for idx in 4..8 { + buf[idx] = 0 + } } write.write_all(&buf).await?; } else { let mut buf = vec![0; (segment_count & !1) * 4]; for idx in 1..segment_count { - buf[(idx - 1) * 4..idx * 4].copy_from_slice( - &((segments[idx].len() / 8) as u32).to_le_bytes()); + buf[(idx - 1) * 4..idx * 4] + .copy_from_slice(&((segments[idx].len() / 8) as u32).to_le_bytes()); } if segment_count % 2 == 0 { - for idx in (buf.len() - 4)..(buf.len()) { buf[idx] = 0 } + for idx in (buf.len() - 4)..(buf.len()) { + buf[idx] = 0 + } } write.write_all(&buf).await?; } @@ -215,7 +255,8 @@ async fn write_segment_table(mut write: W, segments: &[&[u8]]) -> ::std::io:: /// Writes segments to `write`. async fn write_segments(mut write: W, segments: &[&[u8]]) -> Result<()> - where W: AsyncWrite + Unpin +where + W: AsyncWrite + Unpin, { for i in 0..segments.len() { write.write_all(segments[i]).await?; @@ -223,8 +264,6 @@ async fn write_segments(mut write: W, segments: &[&[u8]]) -> Result<()> Ok(()) } - - #[cfg(test)] pub mod test { use std::cmp; @@ -232,20 +271,15 @@ pub mod test { use std::pin::Pin; use std::task::{Context, Poll}; - use futures::{AsyncRead, AsyncWrite}; use futures::io::Cursor; + use futures::{AsyncRead, AsyncWrite}; use quickcheck::{quickcheck, TestResult}; - use capnp::{message, OutputSegments}; use capnp::message::ReaderSegments; + use capnp::{message, OutputSegments}; - use super::{ - AsOutputSegments, - try_read_message, - read_segment_table, - write_message, - }; + use super::{read_segment_table, try_read_message, write_message, AsOutputSegments}; #[test] fn test_read_segment_table() { @@ -253,58 +287,103 @@ pub mod test { let mut buf = vec![]; buf.extend( - [0,0,0,0, // 1 segments - 0,0,0,0] // 0 length - ); - let segment_lengths = exec.run_until(read_segment_table(Cursor::new(&buf[..]), - message::ReaderOptions::new())).unwrap().unwrap(); + [ + 0, 0, 0, 0, // 1 segments + 0, 0, 0, 0, + ], // 0 length + ); + let segment_lengths = exec + .run_until(read_segment_table( + Cursor::new(&buf[..]), + message::ReaderOptions::new(), + )) + .unwrap() + .unwrap(); assert_eq!(0, segment_lengths.total_words()); - assert_eq!(vec![(0,0)], segment_lengths.to_segment_indices()); + assert_eq!(vec![(0, 0)], segment_lengths.to_segment_indices()); buf.clear(); - buf.extend([0,0,0,0, // 1 segments - 1,0,0,0] // 1 length - ); - - let segment_lengths = exec.run_until(read_segment_table(&mut Cursor::new(&buf[..]), - message::ReaderOptions::new())).unwrap().unwrap(); + buf.extend( + [ + 0, 0, 0, 0, // 1 segments + 1, 0, 0, 0, + ], // 1 length + ); + + let segment_lengths = exec + .run_until(read_segment_table( + &mut Cursor::new(&buf[..]), + message::ReaderOptions::new(), + )) + .unwrap() + .unwrap(); assert_eq!(1, segment_lengths.total_words()); - assert_eq!(vec![(0,1)], segment_lengths.to_segment_indices()); + assert_eq!(vec![(0, 1)], segment_lengths.to_segment_indices()); buf.clear(); - buf.extend([1,0,0,0, // 2 segments - 1,0,0,0, // 1 length - 1,0,0,0, // 1 length - 0,0,0,0] // padding - ); - let segment_lengths = exec.run_until(read_segment_table(&mut Cursor::new(&buf[..]), - message::ReaderOptions::new())).unwrap().unwrap(); + buf.extend( + [ + 1, 0, 0, 0, // 2 segments + 1, 0, 0, 0, // 1 length + 1, 0, 0, 0, // 1 length + 0, 0, 0, 0, + ], // padding + ); + let segment_lengths = exec + .run_until(read_segment_table( + &mut Cursor::new(&buf[..]), + message::ReaderOptions::new(), + )) + .unwrap() + .unwrap(); assert_eq!(2, segment_lengths.total_words()); - assert_eq!(vec![(0,1), (1, 2)], segment_lengths.to_segment_indices()); + assert_eq!(vec![(0, 1), (1, 2)], segment_lengths.to_segment_indices()); buf.clear(); - buf.extend([2,0,0,0, // 3 segments - 1,0,0,0, // 1 length - 1,0,0,0, // 1 length - 0,1,0,0] // 256 length - ); - let segment_lengths = exec.run_until(read_segment_table(&mut Cursor::new(&buf[..]), - message::ReaderOptions::new())).unwrap().unwrap(); + buf.extend( + [ + 2, 0, 0, 0, // 3 segments + 1, 0, 0, 0, // 1 length + 1, 0, 0, 0, // 1 length + 0, 1, 0, 0, + ], // 256 length + ); + let segment_lengths = exec + .run_until(read_segment_table( + &mut Cursor::new(&buf[..]), + message::ReaderOptions::new(), + )) + .unwrap() + .unwrap(); assert_eq!(258, segment_lengths.total_words()); - assert_eq!(vec![(0,1), (1, 2), (2, 258)], segment_lengths.to_segment_indices()); + assert_eq!( + vec![(0, 1), (1, 2), (2, 258)], + segment_lengths.to_segment_indices() + ); buf.clear(); - buf.extend([3,0,0,0, // 4 segments - 77,0,0,0, // 77 length - 23,0,0,0, // 23 length - 1,0,0,0, // 1 length - 99,0,0,0, // 99 length - 0,0,0,0] // padding - ); - let segment_lengths = exec.run_until(read_segment_table(&mut Cursor::new(&buf[..]), - message::ReaderOptions::new())).unwrap().unwrap(); + buf.extend( + [ + 3, 0, 0, 0, // 4 segments + 77, 0, 0, 0, // 77 length + 23, 0, 0, 0, // 23 length + 1, 0, 0, 0, // 1 length + 99, 0, 0, 0, // 99 length + 0, 0, 0, 0, + ], // padding + ); + let segment_lengths = exec + .run_until(read_segment_table( + &mut Cursor::new(&buf[..]), + message::ReaderOptions::new(), + )) + .unwrap() + .unwrap(); assert_eq!(200, segment_lengths.total_words()); - assert_eq!(vec![(0,77), (77, 100), (100, 101), (101, 200)], segment_lengths.to_segment_indices()); + assert_eq!( + vec![(0, 77), (77, 100), (100, 101), (101, 200)], + segment_lengths.to_segment_indices() + ); buf.clear(); } @@ -313,84 +392,129 @@ pub mod test { let mut exec = futures::executor::LocalPool::new(); let mut buf = vec![]; - buf.extend([0,2,0,0]); // 513 segments + buf.extend([0, 2, 0, 0]); // 513 segments buf.extend([0; 513 * 4]); - assert!(exec.run_until(read_segment_table(Cursor::new(&buf[..]), - message::ReaderOptions::new())).is_err()); + assert!(exec + .run_until(read_segment_table( + Cursor::new(&buf[..]), + message::ReaderOptions::new() + )) + .is_err()); buf.clear(); - buf.extend([0,0,0,0]); // 1 segments - assert!(exec.run_until(read_segment_table(Cursor::new(&buf[..]), - message::ReaderOptions::new())).is_err()); + buf.extend([0, 0, 0, 0]); // 1 segments + assert!(exec + .run_until(read_segment_table( + Cursor::new(&buf[..]), + message::ReaderOptions::new() + )) + .is_err()); buf.clear(); - buf.extend([0,0,0,0]); // 1 segments + buf.extend([0, 0, 0, 0]); // 1 segments buf.extend([0; 3]); - assert!(exec.run_until(read_segment_table(Cursor::new(&buf[..]), - message::ReaderOptions::new())).is_err()); + assert!(exec + .run_until(read_segment_table( + Cursor::new(&buf[..]), + message::ReaderOptions::new() + )) + .is_err()); buf.clear(); - buf.extend([255,255,255,255]); // 0 segments - assert!(exec.run_until(read_segment_table(Cursor::new(&buf[..]), - message::ReaderOptions::new())).is_err()); + buf.extend([255, 255, 255, 255]); // 0 segments + assert!(exec + .run_until(read_segment_table( + Cursor::new(&buf[..]), + message::ReaderOptions::new() + )) + .is_err()); buf.clear(); } fn construct_segment_table(segments: &[&[u8]]) -> Vec { let mut exec = futures::executor::LocalPool::new(); let mut buf = vec![]; - exec.run_until(super::write_segment_table(&mut buf, segments)).unwrap(); + exec.run_until(super::write_segment_table(&mut buf, segments)) + .unwrap(); buf } #[test] fn test_construct_segment_table() { - let segment_0: [u8; 0] = []; - let segment_1 = [1,0,0,0,0,0,0,0]; + let segment_1 = [1, 0, 0, 0, 0, 0, 0, 0]; let segment_199 = [197; 199 * 8]; let buf = construct_segment_table(&[&segment_0]); - assert_eq!(&[0,0,0,0, // 1 segments - 0,0,0,0], // 0 length - &buf[..]); + assert_eq!( + &[ + 0, 0, 0, 0, // 1 segments + 0, 0, 0, 0 + ], // 0 length + &buf[..] + ); let buf = construct_segment_table(&[&segment_1]); - assert_eq!(&[0,0,0,0, // 1 segments - 1,0,0,0], // 1 length - &buf[..]); + assert_eq!( + &[ + 0, 0, 0, 0, // 1 segments + 1, 0, 0, 0 + ], // 1 length + &buf[..] + ); let buf = construct_segment_table(&[&segment_199]); - assert_eq!(&[0,0,0,0, // 1 segments - 199,0,0,0], // 199 length - &buf[..]); + assert_eq!( + &[ + 0, 0, 0, 0, // 1 segments + 199, 0, 0, 0 + ], // 199 length + &buf[..] + ); let buf = construct_segment_table(&[&segment_0, &segment_1]); - assert_eq!(&[1,0,0,0, // 2 segments - 0,0,0,0, // 0 length - 1,0,0,0, // 1 length - 0,0,0,0], // padding - &buf[..]); + assert_eq!( + &[ + 1, 0, 0, 0, // 2 segments + 0, 0, 0, 0, // 0 length + 1, 0, 0, 0, // 1 length + 0, 0, 0, 0 + ], // padding + &buf[..] + ); let buf = construct_segment_table(&[&segment_199, &segment_1, &segment_199, &segment_0]); - assert_eq!(&[3,0,0,0, // 4 segments - 199,0,0,0, // 199 length - 1,0,0,0, // 1 length - 199,0,0,0, // 199 length - 0,0,0,0, // 0 length - 0,0,0,0], // padding - &buf[..]); - - let buf = construct_segment_table( - &[&segment_199, &segment_1, &segment_199, &segment_0, &segment_1]); - assert_eq!(&[4,0,0,0, // 5 segments - 199,0,0,0, // 199 length - 1,0,0,0, // 1 length - 199,0,0,0, // 199 length - 0,0,0,0, // 0 length - 1,0,0,0], // 1 length - &buf[..]); + assert_eq!( + &[ + 3, 0, 0, 0, // 4 segments + 199, 0, 0, 0, // 199 length + 1, 0, 0, 0, // 1 length + 199, 0, 0, 0, // 199 length + 0, 0, 0, 0, // 0 length + 0, 0, 0, 0 + ], // padding + &buf[..] + ); + + let buf = construct_segment_table(&[ + &segment_199, + &segment_1, + &segment_199, + &segment_0, + &segment_1, + ]); + assert_eq!( + &[ + 4, 0, 0, 0, // 5 segments + 199, 0, 0, 0, // 199 length + 1, 0, 0, 0, // 1 length + 199, 0, 0, 0, // 199 length + 0, 0, 0, 0, // 0 length + 1, 0, 0, 0 + ], // 1 length + &buf[..] + ); } impl AsOutputSegments for Vec> { @@ -400,15 +524,20 @@ pub mod test { } else if self.len() == 1 { OutputSegments::SingleSegment([capnp::Word::words_to_bytes(&self[0][..])]) } else { - OutputSegments::MultiSegment(self.iter() - .map(|segment| capnp::Word::words_to_bytes(&segment[..])) - .collect::>()) + OutputSegments::MultiSegment( + self.iter() + .map(|segment| capnp::Word::words_to_bytes(&segment[..])) + .collect::>(), + ) } } } /// Wraps a `Read` instance and introduces blocking. - pub(crate) struct BlockingRead where R: Read { + pub(crate) struct BlockingRead + where + R: Read, + { /// The wrapped reader pub read: R, @@ -419,14 +548,28 @@ pub mod test { idx: usize, } - impl BlockingRead where R: Read { + impl BlockingRead + where + R: Read, + { pub(crate) fn new(read: R, blocking_period: usize) -> BlockingRead { - BlockingRead { read, blocking_period, idx: 0 } + BlockingRead { + read, + blocking_period, + idx: 0, + } } } - impl AsyncRead for BlockingRead where R: Read + Unpin { - fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll> { + impl AsyncRead for BlockingRead + where + R: Read + Unpin, + { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context, + buf: &mut [u8], + ) -> Poll> { if self.idx == 0 { self.idx = self.blocking_period; cx.waker().clone().wake(); @@ -444,7 +587,10 @@ pub mod test { } /// Wraps a `Write` instance and introduces blocking. - pub(crate) struct BlockingWrite where W: Write { + pub(crate) struct BlockingWrite + where + W: Write, + { /// The wrapped writer writer: W, @@ -455,17 +601,31 @@ pub mod test { idx: usize, } - impl BlockingWrite where W: Write { + impl BlockingWrite + where + W: Write, + { pub(crate) fn new(writer: W, blocking_period: usize) -> BlockingWrite { - BlockingWrite { writer, blocking_period, idx: 0 } + BlockingWrite { + writer, + blocking_period, + idx: 0, + } } pub(crate) fn into_writer(self) -> W { self.writer } } - impl AsyncWrite for BlockingWrite where W: Write + Unpin { - fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll> { + impl AsyncWrite for BlockingWrite + where + W: Write + Unpin, + { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context, + buf: &[u8], + ) -> Poll> { if self.idx == 0 { self.idx = self.blocking_period; cx.waker().clone().wake(); @@ -491,33 +651,39 @@ pub mod test { #[test] fn check_round_trip_async() { - fn round_trip(read_blocking_period: usize, - write_blocking_period: usize, - segments: Vec>) -> TestResult - { + fn round_trip( + read_blocking_period: usize, + write_blocking_period: usize, + segments: Vec>, + ) -> TestResult { if segments.is_empty() || read_blocking_period == 0 || write_blocking_period == 0 { return TestResult::discard(); } let (mut read, segments) = { let cursor = std::io::Cursor::new(Vec::new()); let mut writer = BlockingWrite::new(cursor, write_blocking_period); - futures::executor::block_on(Box::pin(write_message(&mut writer, &segments))).expect("writing"); + futures::executor::block_on(Box::pin(write_message(&mut writer, &segments))) + .expect("writing"); let mut cursor = writer.into_writer(); cursor.set_position(0); (BlockingRead::new(cursor, read_blocking_period), segments) }; - let message = - futures::executor::block_on(Box::pin(try_read_message(&mut read, Default::default()))).expect("reading").unwrap(); + let message = futures::executor::block_on(Box::pin(try_read_message( + &mut read, + Default::default(), + ))) + .expect("reading") + .unwrap(); let message_segments = message.into_segments(); TestResult::from_bool(segments.iter().enumerate().all(|(i, segment)| { - capnp::Word::words_to_bytes(&segment[..]) == message_segments.get_segment(i as u32).unwrap() + capnp::Word::words_to_bytes(&segment[..]) + == message_segments.get_segment(i as u32).unwrap() })) } quickcheck(round_trip as fn(usize, usize, Vec>) -> TestResult); } } - diff --git a/capnp-futures/src/serialize_packed.rs b/capnp-futures/src/serialize_packed.rs index ae5bb650b..94bb25193 100644 --- a/capnp-futures/src/serialize_packed.rs +++ b/capnp-futures/src/serialize_packed.rs @@ -25,8 +25,8 @@ use std::pin::Pin; use std::task::{Context, Poll}; -use capnp::{message, Result}; use capnp::serialize::OwnedSegments; +use capnp::{message, Result}; use futures::{AsyncRead, AsyncWrite}; use crate::serialize::AsOutputSegments; @@ -40,7 +40,10 @@ enum PackedReadStage { } /// An `AsyncRead` wrapper that unpacks packed data. -pub struct PackedRead where R: AsyncRead + Unpin { +pub struct PackedRead +where + R: AsyncRead + Unpin, +{ inner: R, stage: PackedReadStage, @@ -55,28 +58,42 @@ pub struct PackedRead where R: AsyncRead + Unpin { num_run_bytes_remaining: usize, } -impl PackedRead where R: AsyncRead + Unpin { +impl PackedRead +where + R: AsyncRead + Unpin, +{ /// Creates a new `PackedRead` from a `AsyncRead`. For optimal performance, /// `inner` should be a buffered `AsyncRead`. pub fn new(inner: R) -> Self { - Self { inner, - stage: PackedReadStage::Start, - buf: [0; 10], - buf_pos: 0, - buf_size: 10, - num_run_bytes_remaining: 0, + Self { + inner, + stage: PackedReadStage::Start, + buf: [0; 10], + buf_pos: 0, + buf_size: 10, + num_run_bytes_remaining: 0, } } } -impl AsyncRead for PackedRead where R: AsyncRead + Unpin { +impl AsyncRead for PackedRead +where + R: AsyncRead + Unpin, +{ fn poll_read( mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>, - outbuf: &mut [u8] + outbuf: &mut [u8], ) -> Poll> { - let PackedRead { stage, inner, buf, buf_pos, num_run_bytes_remaining, - buf_size, .. } = &mut *self; + let PackedRead { + stage, + inner, + buf, + buf_pos, + num_run_bytes_remaining, + buf_size, + .. + } = &mut *self; loop { match *stage { PackedReadStage::Start => { @@ -101,11 +118,11 @@ impl AsyncRead for PackedRead where R: AsyncRead + Unpin { } } } - }, + } PackedReadStage::WritingZeroes => { let num_zeroes = std::cmp::min(outbuf.len(), *num_run_bytes_remaining); - for ii in 0 .. num_zeroes { + for ii in 0..num_zeroes { outbuf[ii] = 0; } if num_zeroes >= *num_run_bytes_remaining { @@ -117,8 +134,7 @@ impl AsyncRead for PackedRead where R: AsyncRead + Unpin { return Poll::Ready(Ok(num_zeroes)); } PackedReadStage::BufferingWord => { - match Pin::new(&mut *inner).poll_read(cx, - &mut buf[*buf_pos..*buf_size])? { + match Pin::new(&mut *inner).poll_read(cx, &mut buf[*buf_pos..*buf_size])? { Poll::Pending => return Poll::Pending, Poll::Ready(n) => { *buf_pos += n; @@ -132,8 +148,7 @@ impl AsyncRead for PackedRead where R: AsyncRead + Unpin { PackedReadStage::DrainingBuffer => { let mut ii = 0; let mut bitnum = *buf_pos - 1; - while ii < outbuf.len() && bitnum < 8 - { + while ii < outbuf.len() && bitnum < 8 { let is_nonzero = (buf[0] & (1u8 << bitnum)) != 0; outbuf[ii] = buf[*buf_pos] & ((-i8::from(is_nonzero)) as u8); ii += 1; @@ -161,8 +176,7 @@ impl AsyncRead for PackedRead where R: AsyncRead + Unpin { if upper_bound == 0 { *stage = PackedReadStage::Start; } else { - match Pin::new(&mut *inner).poll_read(cx, - &mut outbuf[0 ..upper_bound])? { + match Pin::new(&mut *inner).poll_read(cx, &mut outbuf[0..upper_bound])? { Poll::Pending => return Poll::Pending, Poll::Ready(n) => { if n >= *num_run_bytes_remaining { @@ -185,22 +199,26 @@ impl AsyncRead for PackedRead where R: AsyncRead + Unpin { /// repeatedly until it returns `None`. pub async fn try_read_message( read: R, - options: message::ReaderOptions) --> Result>> - where R: AsyncRead + Unpin + options: message::ReaderOptions, +) -> Result>> +where + R: AsyncRead + Unpin, { let packed_read = PackedRead::new(read); crate::serialize::try_read_message(packed_read, options).await } /// Asynchronously reads a message from `reader`. -pub async fn read_message(reader: R, options: message::ReaderOptions) - -> Result> -where R: AsyncRead + Unpin +pub async fn read_message( + reader: R, + options: message::ReaderOptions, +) -> Result> +where + R: AsyncRead + Unpin, { match try_read_message(reader, options).await? { Some(s) => Ok(s), - None => Err(capnp::Error::failed("Premature end of file".to_string())) + None => Err(capnp::Error::failed("Premature end of file".to_string())), } } @@ -213,7 +231,10 @@ enum PackedWriteStage { } /// An `AsyncWrite` wrapper that packs any data passed into it. -pub struct PackedWrite where W: AsyncWrite + Unpin { +pub struct PackedWrite +where + W: AsyncWrite + Unpin, +{ inner: W, stage: PackedWriteStage, buf: [u8; 8], @@ -226,20 +247,27 @@ pub struct PackedWrite where W: AsyncWrite + Unpin { run_bytes_remaining: usize, } -struct FinishPendingWrites where W: AsyncWrite + Unpin { - inner: PackedWrite +struct FinishPendingWrites +where + W: AsyncWrite + Unpin, +{ + inner: PackedWrite, } -impl FinishPendingWrites where W: AsyncWrite + Unpin { +impl FinishPendingWrites +where + W: AsyncWrite + Unpin, +{ fn new(inner: PackedWrite) -> Self { - Self { - inner - } + Self { inner } } } -impl std::future::Future for FinishPendingWrites where W: AsyncWrite + Unpin { - type Output = std::result::Result<(),capnp::Error>; +impl std::future::Future for FinishPendingWrites +where + W: AsyncWrite + Unpin, +{ + type Output = std::result::Result<(), capnp::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { match self.inner.finish_pending_writes(cx)? { Poll::Ready(()) => Poll::Ready(Ok(())), @@ -251,8 +279,10 @@ impl std::future::Future for FinishPendingWrites where W: AsyncWrite + Un /// Writes the provided message to `writer`. Does not call `writer.flush()`, /// so that multiple successive calls can amortize work when `writer` is /// buffered. -pub async fn write_message(writer: W, message: M) -> Result<()> - where W: AsyncWrite + Unpin, M: AsOutputSegments +pub async fn write_message(writer: W, message: M) -> Result<()> +where + W: AsyncWrite + Unpin, + M: AsOutputSegments, { let mut packed_write = PackedWrite::new(writer); crate::serialize::write_message(&mut packed_write, message).await?; @@ -262,28 +292,39 @@ pub async fn write_message(writer: W, message: M) -> Result<()> FinishPendingWrites::new(packed_write).await } -impl PackedWrite where W: AsyncWrite + Unpin { +impl PackedWrite +where + W: AsyncWrite + Unpin, +{ /// Creates a new `PackedWrite` from a `AsyncWrite`. For optimal performance, /// `inner` should be a buffered `AsyncWrite`. pub fn new(inner: W) -> Self { - Self { inner, - stage: PackedWriteStage::Start, - buf: [0; 8], - buf_pos: 0, - packed_buf: [0; 9], - packed_buf_size: 0, - run_bytes_remaining: 0, + Self { + inner, + stage: PackedWriteStage::Start, + buf: [0; 8], + buf_pos: 0, + packed_buf: [0; 9], + packed_buf_size: 0, + run_bytes_remaining: 0, } } fn poll_write_aux( &mut self, cx: &mut Context<'_>, - mut inbuf: &[u8] + mut inbuf: &[u8], ) -> Poll> { let mut inbuf_bytes_consumed: usize = 0; - let PackedWrite { stage, inner, buf, buf_pos, packed_buf, - packed_buf_size, run_bytes_remaining } = self; + let PackedWrite { + stage, + inner, + buf, + buf_pos, + packed_buf, + packed_buf_size, + run_bytes_remaining, + } = self; loop { match *stage { PackedWriteStage::Start => { @@ -294,7 +335,7 @@ impl PackedWrite where W: AsyncWrite + Unpin { // copy inbuf into buf let buf_bytes_remaining = 8 - *buf_pos; let bytes_to_copy = std::cmp::min(buf_bytes_remaining, inbuf.len()); - buf[*buf_pos ..(*buf_pos + bytes_to_copy)] + buf[*buf_pos..(*buf_pos + bytes_to_copy)] .copy_from_slice(&inbuf[..bytes_to_copy]); inbuf = &inbuf[bytes_to_copy..]; inbuf_bytes_consumed += bytes_to_copy; @@ -303,7 +344,7 @@ impl PackedWrite where W: AsyncWrite + Unpin { if *buf_pos == 8 { // compute tag packed_buf[0] = 0; - let mut packed_buf_idx : usize = 1; + let mut packed_buf_idx: usize = 1; for (ii, b) in buf.iter().enumerate() { if *b != 0 { packed_buf[0] |= 1 << ii; @@ -317,9 +358,9 @@ impl PackedWrite where W: AsyncWrite + Unpin { } } PackedWriteStage::WriteWord => { - match Pin::new(&mut *inner).poll_write( - cx, - &packed_buf[*buf_pos.. *packed_buf_size])? { + match Pin::new(&mut *inner) + .poll_write(cx, &packed_buf[*buf_pos..*packed_buf_size])? + { Poll::Pending => { if inbuf_bytes_consumed == 0 { return Poll::Pending; @@ -351,7 +392,9 @@ impl PackedWrite where W: AsyncWrite + Unpin { let mut zero_bytes_in_word = 0; for (idx, inb) in inbuf.iter().enumerate() { - if idx % 8 == 0 { zero_bytes_in_word = 0; } + if idx % 8 == 0 { + zero_bytes_in_word = 0; + } if *inb == 0 { zero_bytes_in_word += 1; if zero_bytes_in_word > 1 { @@ -369,9 +412,9 @@ impl PackedWrite where W: AsyncWrite + Unpin { } } PackedWriteStage::WriteRunWordCount => { - match Pin::new(&mut *inner).poll_write( - cx, - &[(*run_bytes_remaining / 8) as u8])? { + match Pin::new(&mut *inner) + .poll_write(cx, &[(*run_bytes_remaining / 8) as u8])? + { Poll::Pending => { if inbuf_bytes_consumed == 0 { return Poll::Pending; @@ -382,7 +425,7 @@ impl PackedWrite where W: AsyncWrite + Unpin { Poll::Ready(1) => { if packed_buf[0] == 0 { // we're done here - inbuf = &inbuf[(*run_bytes_remaining) ..]; + inbuf = &inbuf[(*run_bytes_remaining)..]; inbuf_bytes_consumed += *run_bytes_remaining; *buf_pos = 0; *stage = PackedWriteStage::Start; @@ -399,9 +442,7 @@ impl PackedWrite where W: AsyncWrite + Unpin { } PackedWriteStage::WriteUncompressedRun => { - match Pin::new(&mut *inner).poll_write( - cx, - &inbuf[..*run_bytes_remaining])? { + match Pin::new(&mut *inner).poll_write(cx, &inbuf[..*run_bytes_remaining])? { Poll::Pending => { if inbuf_bytes_consumed == 0 { return Poll::Pending; @@ -428,10 +469,10 @@ impl PackedWrite where W: AsyncWrite + Unpin { /// Finish any work that we can do without any new bytes. fn finish_pending_writes( &mut self, - cx: &mut Context<'_> + cx: &mut Context<'_>, ) -> Poll> { - while self.stage == PackedWriteStage::WriteWord || - self.stage == PackedWriteStage::WriteRunWordCount + while self.stage == PackedWriteStage::WriteWord + || self.stage == PackedWriteStage::WriteRunWordCount { match self.poll_write_aux(cx, &[])? { Poll::Pending => return Poll::Pending, @@ -442,18 +483,21 @@ impl PackedWrite where W: AsyncWrite + Unpin { } } -impl AsyncWrite for PackedWrite where W: AsyncWrite + Unpin { +impl AsyncWrite for PackedWrite +where + W: AsyncWrite + Unpin, +{ fn poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, - inbuf: &[u8] + inbuf: &[u8], ) -> Poll> { (*self).poll_write_aux(cx, inbuf) } fn poll_flush( mut self: Pin<&mut Self>, - cx: &mut Context<'_> + cx: &mut Context<'_>, ) -> Poll> { match (*self).finish_pending_writes(cx)? { Poll::Pending => return Poll::Pending, @@ -465,56 +509,51 @@ impl AsyncWrite for PackedWrite where W: AsyncWrite + Unpin { fn poll_close( mut self: Pin<&mut Self>, - cx: &mut Context<'_> + cx: &mut Context<'_>, ) -> Poll> { Pin::new(&mut self.inner).poll_close(cx) } } - #[cfg(test)] pub mod test { - use futures::{AsyncReadExt, AsyncWriteExt}; - use quickcheck::{quickcheck, TestResult}; - use capnp::message::ReaderSegments; use crate::serialize::test::{BlockingRead, BlockingWrite}; use crate::serialize_packed::{PackedRead, PackedWrite}; + use capnp::message::ReaderSegments; + use futures::{AsyncReadExt, AsyncWriteExt}; + use quickcheck::{quickcheck, TestResult}; - pub fn check_unpacks_to(blocking_period: usize, - packed: &[u8], - unpacked: &[u8]) - { - let mut packed_read = - PackedRead::new(crate::serialize::test::BlockingRead::new(packed, - blocking_period)); + pub fn check_unpacks_to(blocking_period: usize, packed: &[u8], unpacked: &[u8]) { + let mut packed_read = PackedRead::new(crate::serialize::test::BlockingRead::new( + packed, + blocking_period, + )); let mut bytes: Vec = vec![0; unpacked.len()]; - futures::executor::block_on( - Box::pin(packed_read.read_exact(&mut bytes))).expect("reading"); + futures::executor::block_on(Box::pin(packed_read.read_exact(&mut bytes))).expect("reading"); assert!(packed_read.inner.read.is_empty()); // nothing left to read assert_eq!(bytes, unpacked); } - - pub fn check_packing_with_periods(read_blocking_period: usize, - write_blocking_period: usize, - unpacked: &[u8], - packed: &[u8]) - { + pub fn check_packing_with_periods( + read_blocking_period: usize, + write_blocking_period: usize, + unpacked: &[u8], + packed: &[u8], + ) { // -------- // write let mut bytes: Vec = vec![0; packed.len()]; { - let mut packed_write = - PackedWrite::new(crate::serialize::test::BlockingWrite::new( - &mut bytes[..], - write_blocking_period)); - futures::executor::block_on( - Box::pin(packed_write.write_all(unpacked))).expect("writing"); - futures::executor::block_on( - Box::pin(packed_write.flush())).expect("flushing"); + let mut packed_write = PackedWrite::new(crate::serialize::test::BlockingWrite::new( + &mut bytes[..], + write_blocking_period, + )); + futures::executor::block_on(Box::pin(packed_write.write_all(unpacked))) + .expect("writing"); + futures::executor::block_on(Box::pin(packed_write.flush())).expect("flushing"); } assert_eq!(bytes, packed); @@ -524,12 +563,10 @@ pub mod test { check_unpacks_to(read_blocking_period, packed, unpacked); } - pub fn check_packing(unpacked: &[u8], - packed: &[u8]) - { - for ii in 1 .. 10 { - for jj in 1 .. 10 { - check_packing_with_periods(ii, jj, unpacked,packed); + pub fn check_packing(unpacked: &[u8], packed: &[u8]) { + for ii in 1..10 { + for jj in 1..10 { + check_packing_with_periods(ii, jj, unpacked, packed); } } } @@ -537,69 +574,110 @@ pub mod test { #[test] pub fn simple_packing() { check_packing(&[], &[]); - check_packing(&[0; 8], &[0,0]); - check_packing(&[0,0,12,0,0,34,0,0], &[0x24,12,34]); - check_packing(&[1,3,2,4,5,7,6,8], &[0xff,1,3,2,4,5,7,6,8,0]); - check_packing(&[0,0,0,0,0,0,0,0,1,3,2,4,5,7,6,8], &[0,0,0xff,1,3,2,4,5,7,6,8,0]); - check_packing(&[0,0,12,0,0,34,0,0,1,3,2,4,5,7,6,8], &[0x24,12,34,0xff,1,3,2,4,5,7,6,8,0]); + check_packing(&[0; 8], &[0, 0]); + check_packing(&[0, 0, 12, 0, 0, 34, 0, 0], &[0x24, 12, 34]); + check_packing( + &[1, 3, 2, 4, 5, 7, 6, 8], + &[0xff, 1, 3, 2, 4, 5, 7, 6, 8, 0], + ); + check_packing( + &[0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 4, 5, 7, 6, 8], + &[0, 0, 0xff, 1, 3, 2, 4, 5, 7, 6, 8, 0], + ); + check_packing( + &[0, 0, 12, 0, 0, 34, 0, 0, 1, 3, 2, 4, 5, 7, 6, 8], + &[0x24, 12, 34, 0xff, 1, 3, 2, 4, 5, 7, 6, 8, 0], + ); - check_packing(&[1,3,2,4,5,7,6,8,8,6,7,4,5,2,3,1], &[0xff,1,3,2,4,5,7,6,8,1,8,6,7,4,5,2,3,1]); check_packing( - &[1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 0,2,4,0,9,0,5,1], - &[0xff,1,2,3,4,5,6,7,8, 3, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, - 0xd6,2,4,9,5,1]); + &[1, 3, 2, 4, 5, 7, 6, 8, 8, 6, 7, 4, 5, 2, 3, 1], + &[0xff, 1, 3, 2, 4, 5, 7, 6, 8, 1, 8, 6, 7, 4, 5, 2, 3, 1], + ); + check_packing( + &[ + 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, + 5, 6, 7, 8, 0, 2, 4, 0, 9, 0, 5, 1, + ], + &[ + 0xff, 1, 2, 3, 4, 5, 6, 7, 8, 3, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, + 2, 3, 4, 5, 6, 7, 8, 0xd6, 2, 4, 9, 5, 1, + ], + ); check_packing( - &[1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 6,2,4,3,9,0,5,1, 1,2,3,4,5,6,7,8, 0,2,4,0,9,0,5,1], - &[0xff,1,2,3,4,5,6,7,8, 3, 1,2,3,4,5,6,7,8, 6,2,4,3,9,0,5,1, 1,2,3,4,5,6,7,8, - 0xd6,2,4,9,5,1]); + &[ + 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 6, 2, 4, 3, 9, 0, 5, 1, 1, 2, 3, 4, + 5, 6, 7, 8, 0, 2, 4, 0, 9, 0, 5, 1, + ], + &[ + 0xff, 1, 2, 3, 4, 5, 6, 7, 8, 3, 1, 2, 3, 4, 5, 6, 7, 8, 6, 2, 4, 3, 9, 0, 5, 1, 1, + 2, 3, 4, 5, 6, 7, 8, 0xd6, 2, 4, 9, 5, 1, + ], + ); check_packing( - &[8,0,100,6,0,1,1,2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,0,2,0,3,1], - &[0xed,8,100,6,1,1,2, 0,2, 0xd4,1,2,3,1]); - check_packing(&[0; 16], &[0,1]); - check_packing(&[0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0], &[0,2]); + &[ + 8, 0, 100, 6, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 1, + ], + &[0xed, 8, 100, 6, 1, 1, 2, 0, 2, 0xd4, 1, 2, 3, 1], + ); + check_packing(&[0; 16], &[0, 1]); + check_packing( + &[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + &[0, 2], + ); } - fn round_trip(read_blocking_period: usize, - write_blocking_period: usize, - segments: Vec>) -> TestResult - { + fn round_trip( + read_blocking_period: usize, + write_blocking_period: usize, + segments: Vec>, + ) -> TestResult { if segments.is_empty() || read_blocking_period == 0 || write_blocking_period == 0 { return TestResult::discard(); } let (mut read, segments) = { let cursor = std::io::Cursor::new(Vec::new()); let mut writer = BlockingWrite::new(cursor, write_blocking_period); - futures::executor::block_on(Box::pin( - crate::serialize_packed::write_message( - &mut writer, - &segments))).expect("writing"); + futures::executor::block_on(Box::pin(crate::serialize_packed::write_message( + &mut writer, + &segments, + ))) + .expect("writing"); futures::executor::block_on(Box::pin(writer.flush())).expect("writing"); - let mut cursor = writer.into_writer(); cursor.set_position(0); (BlockingRead::new(cursor, read_blocking_period), segments) }; - let message = - futures::executor::block_on(Box::pin( - crate::serialize_packed::try_read_message( - &mut read, - Default::default()))).expect("reading").unwrap(); + let message = futures::executor::block_on(Box::pin( + crate::serialize_packed::try_read_message(&mut read, Default::default()), + )) + .expect("reading") + .unwrap(); let message_segments = message.into_segments(); TestResult::from_bool(segments.iter().enumerate().all(|(i, segment)| { - capnp::Word::words_to_bytes(&segment[..]) == message_segments.get_segment(i as u32).unwrap() + capnp::Word::words_to_bytes(&segment[..]) + == message_segments.get_segment(i as u32).unwrap() })) } #[test] fn check_packed_round_trip_async_bug() { - assert!(!round_trip(1,1, - vec![vec![capnp::word(8, 14, 90, 7, 21, 13, 59, 17), - capnp::word(0, 31, 21, 73, 0, 54, 61, 12)]]).is_failure()); + assert!(!round_trip( + 1, + 1, + vec![vec![ + capnp::word(8, 14, 90, 7, 21, 13, 59, 17), + capnp::word(0, 31, 21, 73, 0, 54, 61, 12) + ]] + ) + .is_failure()); } #[test] diff --git a/capnp-futures/src/write_queue.rs b/capnp-futures/src/write_queue.rs index 8ae4dcaeb..ab5e919e0 100644 --- a/capnp-futures/src/write_queue.rs +++ b/capnp-futures/src/write_queue.rs @@ -18,32 +18,45 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use futures::future::Future; use futures::channel::oneshot; +use futures::future::Future; use futures::{AsyncWrite, AsyncWriteExt, StreamExt, TryFutureExt}; -use capnp::{Error}; +use capnp::Error; -use crate::serialize::{AsOutputSegments}; +use crate::serialize::AsOutputSegments; -enum Item where M: AsOutputSegments { +enum Item +where + M: AsOutputSegments, +{ Message(M, oneshot::Sender), - Done(Result<(), Error>, oneshot::Sender<()>) + Done(Result<(), Error>, oneshot::Sender<()>), } /// A handle that allows message to be sent to a write queue`. -pub struct Sender where M: AsOutputSegments { +pub struct Sender +where + M: AsOutputSegments, +{ sender: futures::channel::mpsc::UnboundedSender>, } -impl Clone for Sender where M: AsOutputSegments { +impl Clone for Sender +where + M: AsOutputSegments, +{ fn clone(&self) -> Sender { - Sender { sender: self.sender.clone() } + Sender { + sender: self.sender.clone(), + } } } /// Creates a new WriteQueue that wraps the given writer. -pub fn write_queue(mut writer: W) -> (Sender, impl Future> ) - where W: AsyncWrite + Unpin , M: AsOutputSegments +pub fn write_queue(mut writer: W) -> (Sender, impl Future>) +where + W: AsyncWrite + Unpin, + M: AsOutputSegments, { let (tx, mut rx) = futures::channel::mpsc::unbounded(); @@ -69,16 +82,18 @@ pub fn write_queue(mut writer: W) -> (Sender, impl Future Sender where M: AsOutputSegments { +impl Sender +where + M: AsOutputSegments, +{ /// Enqueues a message to be written. The returned future resolves once the write /// has completed. - pub fn send(&mut self, message: M) -> impl Future> + Unpin { + pub fn send(&mut self, message: M) -> impl Future> + Unpin { let (complete, oneshot) = oneshot::channel(); let _ = self.sender.unbounded_send(Item::Message(message, complete)); - oneshot.map_err( - |oneshot::Canceled| Error::disconnected("WriteQueue has terminated".into())) + oneshot.map_err(|oneshot::Canceled| Error::disconnected("WriteQueue has terminated".into())) } /// Returns the number of messages queued to be written, not including any in-progress write. @@ -89,12 +104,15 @@ impl Sender where M: AsOutputSegments { /// Commands the queue to stop writing messages once it is empty. After this method has been called, /// any new calls to `send()` will return a future that immediately resolves to an error. /// If the passed-in `result` is an error, then the `WriteQueue` will resolve to that error. - pub fn terminate(&mut self, result: Result<(), Error>) -> impl Future> + Unpin { + pub fn terminate( + &mut self, + result: Result<(), Error>, + ) -> impl Future> + Unpin { let (complete, receiver) = oneshot::channel(); let _ = self.sender.unbounded_send(Item::Done(result, complete)); - receiver.map_err( - |oneshot::Canceled| Error::disconnected("WriteQueue has terminated".into())) + receiver + .map_err(|oneshot::Canceled| Error::disconnected("WriteQueue has terminated".into())) } } diff --git a/capnp-futures/test/test.rs b/capnp-futures/test/test.rs index 8939ae74a..557069999 100644 --- a/capnp-futures/test/test.rs +++ b/capnp-futures/test/test.rs @@ -20,15 +20,15 @@ // THE SOFTWARE. pub mod addressbook_capnp { - include!(concat!(env!("OUT_DIR"), "/addressbook_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/addressbook_capnp.rs")); } #[cfg(test)] mod tests { - use futures::task::{LocalSpawnExt}; + use crate::addressbook_capnp::{address_book, person}; use capnp::message; use capnp_futures::serialize; - use crate::addressbook_capnp::{address_book, person}; + use futures::task::LocalSpawnExt; fn populate_address_book(address_book: address_book::Builder) { let mut people = address_book.init_people(2); @@ -40,7 +40,10 @@ mod tests { { let mut alice_phones = alice.reborrow().init_phones(1); alice_phones.reborrow().get(0).set_number("555-1212"); - alice_phones.reborrow().get(0).set_type(person::phone_number::Type::Mobile); + alice_phones + .reborrow() + .get(0) + .set_type(person::phone_number::Type::Mobile); } alice.get_employment().set_school("MIT"); } @@ -53,9 +56,15 @@ mod tests { { let mut bob_phones = bob.reborrow().init_phones(2); bob_phones.reborrow().get(0).set_number("555-4567"); - bob_phones.reborrow().get(0).set_type(person::phone_number::Type::Home); + bob_phones + .reborrow() + .get(0) + .set_type(person::phone_number::Type::Home); bob_phones.reborrow().get(1).set_number("555-7654"); - bob_phones.reborrow().get(1).set_type(person::phone_number::Type::Work); + bob_phones + .reborrow() + .get(1) + .set_type(person::phone_number::Type::Work); } bob.get_employment().set_unemployed(()); } @@ -78,8 +87,8 @@ mod tests { fn write_stream_and_read_queue() { use capnp; use capnp_futures; - use futures::future::{FutureExt}; - use futures::stream::{StreamExt}; + use futures::future::FutureExt; + use futures::stream::StreamExt; use std::cell::Cell; use std::rc::Rc; @@ -93,15 +102,13 @@ mod tests { let messages_read = Rc::new(Cell::new(0u32)); let messages_read1 = messages_read.clone(); - let done_reading = read_stream.for_each(|m| { - match m { - Err(e) => panic!("read error: {:?}", e), - Ok(msg) => { - let address_book = msg.get_root::().unwrap(); - read_address_book(address_book); - messages_read.set(messages_read.get() + 1); - futures::future::ready(()) - } + let done_reading = read_stream.for_each(|m| match m { + Err(e) => panic!("read error: {:?}", e), + Ok(msg) => { + let address_book = msg.get_root::().unwrap(); + read_address_book(address_book); + messages_read.set(messages_read.get() + 1); + futures::future::ready(()) } }); @@ -110,7 +117,7 @@ mod tests { let mut m = capnp::message::Builder::new_default(); populate_address_book(m.init_root()); - spawner.spawn_local(sender.send(m).map(|_|())).unwrap(); + spawner.spawn_local(sender.send(m).map(|_| ())).unwrap(); drop(sender); pool.run_until(io); assert_eq!(messages_read1.get(), 1); @@ -128,16 +135,15 @@ mod tests { let mut pool = futures::executor::LocalPool::new(); let (stream0, stream1) = async_byte_channel::channel(); let f0 = serialize::write_message(stream0, message) - .map_err(|e| panic!("write error {:?}", e)).map(|_|()); - let f1 = - serialize::try_read_message(stream1, capnp::message::ReaderOptions::new()).and_then(|maybe_message_reader| { - match maybe_message_reader { - None => panic!("did not get message"), - Some(m) => { - let address_book = m.get_root::().unwrap(); - read_address_book(address_book); - futures::future::ready(Ok::<(),capnp::Error>(())) - } + .map_err(|e| panic!("write error {:?}", e)) + .map(|_| ()); + let f1 = serialize::try_read_message(stream1, capnp::message::ReaderOptions::new()) + .and_then(|maybe_message_reader| match maybe_message_reader { + None => panic!("did not get message"), + Some(m) => { + let address_book = m.get_root::().unwrap(); + read_address_book(address_book); + futures::future::ready(Ok::<(), capnp::Error>(())) } }); @@ -145,7 +151,6 @@ mod tests { pool.run_until(f1).unwrap(); } - #[test] fn single_segment() { fill_and_send_message(capnp::message::Builder::new_default()); @@ -154,7 +159,8 @@ mod tests { #[test] fn multi_segment() { let builder_options = capnp::message::HeapAllocator::new() - .first_segment_words(1).allocation_strategy(capnp::message::AllocationStrategy::FixedSize); + .first_segment_words(1) + .allocation_strategy(capnp::message::AllocationStrategy::FixedSize); fill_and_send_message(capnp::message::Builder::new(builder_options)); } @@ -169,6 +175,7 @@ mod tests { fn static_lifetime_not_required_on_highlevel() { let (mut write, mut read) = async_byte_channel::channel(); let _ = capnp_futures::ReadStream::new(&mut read, message::ReaderOptions::default()); - let _ = capnp_futures::write_queue::<_, message::Builder>(&mut write); + let _ = + capnp_futures::write_queue::<_, message::Builder>(&mut write); } } diff --git a/capnp-rpc/examples/calculator/build.rs b/capnp-rpc/examples/calculator/build.rs index 21bb19888..6fadd5327 100644 --- a/capnp-rpc/examples/calculator/build.rs +++ b/capnp-rpc/examples/calculator/build.rs @@ -1,3 +1,5 @@ fn main() -> Result<(), Box> { - Ok(capnpc::CompilerCommand::new().file("calculator.capnp").run()?) + Ok(capnpc::CompilerCommand::new() + .file("calculator.capnp") + .run()?) } diff --git a/capnp-rpc/examples/calculator/client.rs b/capnp-rpc/examples/calculator/client.rs index 6dc9d2cea..d608dcb9e 100644 --- a/capnp-rpc/examples/calculator/client.rs +++ b/capnp-rpc/examples/calculator/client.rs @@ -19,24 +19,26 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use capnp_rpc::{RpcSystem, pry, twoparty, rpc_twoparty_capnp}; use crate::calculator_capnp::calculator; use capnp::capability::Promise; +use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, RpcSystem}; -use futures::{AsyncReadExt}; +use futures::AsyncReadExt; #[derive(Clone, Copy)] pub struct PowerFunction; impl calculator::function::Server for PowerFunction { - fn call(&mut self, - params: calculator::function::CallParams, - mut results: calculator::function::CallResults) - -> Promise<(), ::capnp::Error> - { + fn call( + &mut self, + params: calculator::function::CallParams, + mut results: calculator::function::CallResults, + ) -> Promise<(), ::capnp::Error> { let params = pry!(pry!(params.get()).get_params()); if params.len() != 2 { - Promise::err(::capnp::Error::failed("Wrong number of parameters".to_string())) + Promise::err(::capnp::Error::failed( + "Wrong number of parameters".to_string(), + )) } else { results.get().set_value(params.get(0).powf(params.get(1))); Promise::ok(()) @@ -53,19 +55,23 @@ pub async fn main() -> Result<(), Box> { tokio::task::LocalSet::new().run_until(try_main(args)).await } -async fn try_main(args: Vec) -> Result<(), Box> -{ +async fn try_main(args: Vec) -> Result<(), Box> { use std::net::ToSocketAddrs; - let addr = args[2].to_socket_addrs()?.next().expect("could not parse address"); + let addr = args[2] + .to_socket_addrs()? + .next() + .expect("could not parse address"); let stream = tokio::net::TcpStream::connect(&addr).await?; stream.set_nodelay(true)?; let (reader, writer) = tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); - let network = - Box::new(twoparty::VatNetwork::new(reader, writer, - rpc_twoparty_capnp::Side::Client, - Default::default())); + let network = Box::new(twoparty::VatNetwork::new( + reader, + writer, + rpc_twoparty_capnp::Side::Client, + Default::default(), + )); let mut rpc_system = RpcSystem::new(network, None); let calculator: calculator::Client = rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); @@ -188,22 +194,38 @@ async fn try_main(args: Vec) -> Result<(), Box> let mut add3_call = add3_request.get().init_expression().init_call(); add3_call.set_function(add.clone()); let mut add3_params = add3_call.init_params(2); - add3_params.reborrow().get(0).set_previous_result(multiply_result.clone()); + add3_params + .reborrow() + .get(0) + .set_previous_result(multiply_result.clone()); add3_params.reborrow().get(1).set_literal(3.0); } - let add3_promise = add3_request.send().pipeline.get_value().read_request().send(); + let add3_promise = add3_request + .send() + .pipeline + .get_value() + .read_request() + .send(); let mut add5_request = calculator.evaluate_request(); { let mut add5_call = add5_request.get().init_expression().init_call(); add5_call.set_function(add); let mut add5_params = add5_call.init_params(2); - add5_params.reborrow().get(0).set_previous_result(multiply_result); + add5_params + .reborrow() + .get(0) + .set_previous_result(multiply_result); add5_params.get(1).set_literal(5.0); } - let add5_promise = add5_request.send().pipeline.get_value().read_request().send(); + let add5_promise = add5_request + .send() + .pipeline + .get_value() + .read_request() + .send(); // Now wait for the results. assert!(add3_promise.promise.await?.get()?.get_value() == 27.0); @@ -292,7 +314,12 @@ async fn try_main(args: Vec) -> Result<(), Box> f_params.reborrow().get(0).set_literal(12.0); f_params.get(1).set_literal(34.0); } - let f_eval_promise = f_eval_request.send().pipeline.get_value().read_request().send(); + let f_eval_promise = f_eval_request + .send() + .pipeline + .get_value() + .read_request() + .send(); let mut g_eval_request = calculator.evaluate_request(); { @@ -300,7 +327,12 @@ async fn try_main(args: Vec) -> Result<(), Box> g_call.set_function(g); g_call.init_params(1).get(0).set_literal(21.0); } - let g_eval_promise = g_eval_request.send().pipeline.get_value().read_request().send(); + let g_eval_promise = g_eval_request + .send() + .pipeline + .get_value() + .read_request() + .send(); assert!(f_eval_promise.promise.await?.get()?.get_value() == 1234.0); assert!(g_eval_promise.promise.await?.get()?.get_value() == 4244.0); diff --git a/capnp-rpc/examples/calculator/main.rs b/capnp-rpc/examples/calculator/main.rs index 5a804da87..e54641764 100644 --- a/capnp-rpc/examples/calculator/main.rs +++ b/capnp-rpc/examples/calculator/main.rs @@ -20,7 +20,7 @@ // THE SOFTWARE. pub mod calculator_capnp { - include!(concat!(env!("OUT_DIR"), "/calculator_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/calculator_capnp.rs")); } pub mod client; @@ -33,7 +33,7 @@ async fn main() -> Result<(), Box> { match &args[1][..] { "client" => return client::main().await, "server" => return server::main().await, - _ => () + _ => (), } } diff --git a/capnp-rpc/examples/calculator/server.rs b/capnp-rpc/examples/calculator/server.rs index ab2162bb1..9c23efd3b 100644 --- a/capnp-rpc/examples/calculator/server.rs +++ b/capnp-rpc/examples/calculator/server.rs @@ -19,19 +19,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use capnp::Error; use capnp::primitive_list; +use capnp::Error; -use capnp_rpc::{RpcSystem, pry, twoparty, rpc_twoparty_capnp}; +use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, RpcSystem}; use crate::calculator_capnp::calculator; use capnp::capability::Promise; -use futures::{AsyncReadExt, FutureExt, TryFutureExt}; use futures::future; +use futures::{AsyncReadExt, FutureExt, TryFutureExt}; struct ValueImpl { - value: f64 + value: f64, } impl ValueImpl { @@ -41,42 +41,40 @@ impl ValueImpl { } impl calculator::value::Server for ValueImpl { - fn read(&mut self, - _params: calculator::value::ReadParams, - mut results: calculator::value::ReadResults) - -> Promise<(), Error> - { + fn read( + &mut self, + _params: calculator::value::ReadParams, + mut results: calculator::value::ReadResults, + ) -> Promise<(), Error> { results.get().set_value(self.value); Promise::ok(()) } } -fn evaluate_impl(expression: calculator::expression::Reader, - params: Option>) - -> Promise -{ +fn evaluate_impl( + expression: calculator::expression::Reader, + params: Option>, +) -> Promise { match pry!(expression.which()) { - calculator::expression::Literal(v) => { - Promise::ok(v) + calculator::expression::Literal(v) => Promise::ok(v), + calculator::expression::PreviousResult(p) => Promise::from_future( + pry!(p) + .read_request() + .send() + .promise + .map(|v| Ok(v?.get()?.get_value())), + ), + calculator::expression::Parameter(p) => match params { + Some(params) if p < params.len() => Promise::ok(params.get(p)), + _ => Promise::err(Error::failed(format!("bad parameter: {}", p))), }, - calculator::expression::PreviousResult(p) => { - Promise::from_future(pry!(p).read_request().send().promise.map(|v| { - Ok(v?.get()?.get_value()) - })) - } - calculator::expression::Parameter(p) => { - match params { - Some(params) if p < params.len() => { - Promise::ok(params.get(p)) - } - _ => { - Promise::err(Error::failed(format!("bad parameter: {}", p))) - } - } - } calculator::expression::Call(call) => { let func = pry!(call.get_function()); - let eval_params = future::try_join_all(pry!(call.get_params()).iter().map(|p| evaluate_impl(p, params))); + let eval_params = future::try_join_all( + pry!(call.get_params()) + .iter() + .map(|p| evaluate_impl(p, params)), + ); Promise::from_future(async move { let param_values = eval_params.await?; let mut request = func.call_request(); @@ -98,7 +96,10 @@ struct FunctionImpl { } impl FunctionImpl { - fn new(param_count: u32, body: calculator::expression::Reader) -> ::capnp::Result { + fn new( + param_count: u32, + body: calculator::expression::Reader, + ) -> ::capnp::Result { let mut result = FunctionImpl { param_count: param_count, body: ::capnp_rpc::ImbuedMessageBuilder::new(::capnp::message::HeapAllocator::new()), @@ -109,19 +110,24 @@ impl FunctionImpl { } impl calculator::function::Server for FunctionImpl { - fn call(&mut self, - params: calculator::function::CallParams, - mut results: calculator::function::CallResults) - -> Promise<(), Error> - { + fn call( + &mut self, + params: calculator::function::CallParams, + mut results: calculator::function::CallResults, + ) -> Promise<(), Error> { let params = pry!(pry!(params.get()).get_params()); if params.len() != self.param_count { - return Promise::err(Error::failed( - format!("Expected {} parameters but got {}.", self.param_count, params.len()))); + return Promise::err(Error::failed(format!( + "Expected {} parameters but got {}.", + self.param_count, + params.len() + ))); } - let eval = evaluate_impl(pry!(self.body.get_root::()).into_reader(), - Some(params)); + let eval = evaluate_impl( + pry!(self.body.get_root::()).into_reader(), + Some(params), + ); Promise::from_future(async move { results.get().set_value(eval.await?); Ok(()) @@ -135,20 +141,20 @@ pub struct OperatorImpl { } impl calculator::function::Server for OperatorImpl { - fn call(&mut self, - params: calculator::function::CallParams, - mut results: calculator::function::CallResults) - -> Promise<(), Error> - { + fn call( + &mut self, + params: calculator::function::CallParams, + mut results: calculator::function::CallResults, + ) -> Promise<(), Error> { let params = pry!(pry!(params.get()).get_params()); if params.len() != 2 { Promise::err(Error::failed("Wrong number of paramters.".to_string())) } else { let v = match self.op { - calculator::Operator::Add => params.get(0) + params.get(1), - calculator::Operator::Subtract => params.get(0) - params.get(1), - calculator::Operator::Multiply => params.get(0) * params.get(1), - calculator::Operator::Divide => params.get(0) / params.get(1), + calculator::Operator::Add => params.get(0) + params.get(1), + calculator::Operator::Subtract => params.get(0) - params.get(1), + calculator::Operator::Multiply => params.get(0) * params.get(1), + calculator::Operator::Divide => params.get(0) / params.get(1), }; results.get().set_value(v); Promise::ok(()) @@ -159,35 +165,41 @@ impl calculator::function::Server for OperatorImpl { struct CalculatorImpl; impl calculator::Server for CalculatorImpl { - fn evaluate(&mut self, - params: calculator::EvaluateParams, - mut results: calculator::EvaluateResults) - -> Promise<(), Error> - { + fn evaluate( + &mut self, + params: calculator::EvaluateParams, + mut results: calculator::EvaluateResults, + ) -> Promise<(), Error> { Promise::from_future(async move { let v = evaluate_impl(params.get()?.get_expression()?, None).await?; - results.get().set_value(capnp_rpc::new_client(ValueImpl::new(v))); + results + .get() + .set_value(capnp_rpc::new_client(ValueImpl::new(v))); Ok(()) }) } - fn def_function(&mut self, - params: calculator::DefFunctionParams, - mut results: calculator::DefFunctionResults) - -> Promise<(), Error> - { - results.get().set_func( - capnp_rpc::new_client( - pry!(FunctionImpl::new(pry!(params.get()).get_param_count() as u32, - pry!(pry!(params.get()).get_body()))))); + fn def_function( + &mut self, + params: calculator::DefFunctionParams, + mut results: calculator::DefFunctionResults, + ) -> Promise<(), Error> { + results + .get() + .set_func(capnp_rpc::new_client(pry!(FunctionImpl::new( + pry!(params.get()).get_param_count() as u32, + pry!(pry!(params.get()).get_body()) + )))); Promise::ok(()) } - fn get_operator(&mut self, - params: calculator::GetOperatorParams, - mut results: calculator::GetOperatorResults) - -> Promise<(), Error> - { + fn get_operator( + &mut self, + params: calculator::GetOperatorParams, + mut results: calculator::GetOperatorResults, + ) -> Promise<(), Error> { let op = pry!(pry!(params.get()).get_op()); - results.get().set_func(capnp_rpc::new_client(OperatorImpl {op : op})); + results + .get() + .set_func(capnp_rpc::new_client(OperatorImpl { op: op })); Promise::ok(()) } } @@ -200,22 +212,31 @@ pub async fn main() -> Result<(), Box> { return Ok(()); } - let addr = args[2].to_socket_addrs()?.next().expect("could not parse address"); - - tokio::task::LocalSet::new().run_until(async move { - let listener = tokio::net::TcpListener::bind(&addr).await?; - let calc: calculator::Client = capnp_rpc::new_client(CalculatorImpl); - - loop { - let (stream, _) = listener.accept().await?; - stream.set_nodelay(true)?; - let (reader, writer) = tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); - let network = - twoparty::VatNetwork::new(reader, writer, - rpc_twoparty_capnp::Side::Server, Default::default()); - - let rpc_system = RpcSystem::new(Box::new(network), Some(calc.clone().client)); - tokio::task::spawn_local(rpc_system.map_err(|e| println!("error: {:?}", e))); - } - }).await + let addr = args[2] + .to_socket_addrs()? + .next() + .expect("could not parse address"); + + tokio::task::LocalSet::new() + .run_until(async move { + let listener = tokio::net::TcpListener::bind(&addr).await?; + let calc: calculator::Client = capnp_rpc::new_client(CalculatorImpl); + + loop { + let (stream, _) = listener.accept().await?; + stream.set_nodelay(true)?; + let (reader, writer) = + tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); + let network = twoparty::VatNetwork::new( + reader, + writer, + rpc_twoparty_capnp::Side::Server, + Default::default(), + ); + + let rpc_system = RpcSystem::new(Box::new(network), Some(calc.clone().client)); + tokio::task::spawn_local(rpc_system.map_err(|e| println!("error: {:?}", e))); + } + }) + .await } diff --git a/capnp-rpc/examples/hello-world/build.rs b/capnp-rpc/examples/hello-world/build.rs index 7d152227d..8a32a9cc2 100644 --- a/capnp-rpc/examples/hello-world/build.rs +++ b/capnp-rpc/examples/hello-world/build.rs @@ -1,4 +1,6 @@ fn main() -> Result<(), Box> { - capnpc::CompilerCommand::new().file("hello_world.capnp").run()?; + capnpc::CompilerCommand::new() + .file("hello_world.capnp") + .run()?; Ok(()) } diff --git a/capnp-rpc/examples/hello-world/client.rs b/capnp-rpc/examples/hello-world/client.rs index b0e65dd17..865d96748 100644 --- a/capnp-rpc/examples/hello-world/client.rs +++ b/capnp-rpc/examples/hello-world/client.rs @@ -39,34 +39,31 @@ pub async fn main() -> Result<(), Box> { let msg = args[3].to_string(); - tokio::task::LocalSet::new().run_until(async move { - let stream = tokio::net::TcpStream::connect(&addr).await?; - stream.set_nodelay(true)?; - let (reader, writer) = tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); - let rpc_network = Box::new(twoparty::VatNetwork::new( - reader, - writer, - rpc_twoparty_capnp::Side::Client, - Default::default(), - )); - let mut rpc_system = RpcSystem::new(rpc_network, None); - let hello_world: hello_world::Client = - rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); + tokio::task::LocalSet::new() + .run_until(async move { + let stream = tokio::net::TcpStream::connect(&addr).await?; + stream.set_nodelay(true)?; + let (reader, writer) = + tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); + let rpc_network = Box::new(twoparty::VatNetwork::new( + reader, + writer, + rpc_twoparty_capnp::Side::Client, + Default::default(), + )); + let mut rpc_system = RpcSystem::new(rpc_network, None); + let hello_world: hello_world::Client = + rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); - tokio::task::spawn_local(rpc_system); + tokio::task::spawn_local(rpc_system); - let mut request = hello_world.say_hello_request(); - request.get().init_request().set_name(&msg); + let mut request = hello_world.say_hello_request(); + request.get().init_request().set_name(&msg); - let reply = request.send().promise.await?; + let reply = request.send().promise.await?; - println!( - "received: {}", - reply - .get()? - .get_reply()? - .get_message()? - ); - Ok(()) - }).await + println!("received: {}", reply.get()?.get_reply()?.get_message()?); + Ok(()) + }) + .await } diff --git a/capnp-rpc/examples/hello-world/main.rs b/capnp-rpc/examples/hello-world/main.rs index ba0d0b648..cbe5d6e11 100644 --- a/capnp-rpc/examples/hello-world/main.rs +++ b/capnp-rpc/examples/hello-world/main.rs @@ -20,7 +20,7 @@ // THE SOFTWARE. pub mod hello_world_capnp { - include!(concat!(env!("OUT_DIR"), "/hello_world_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/hello_world_capnp.rs")); } pub mod client; @@ -33,7 +33,7 @@ async fn main() -> Result<(), Box> { match &args[1][..] { "client" => return client::main().await, "server" => return server::main().await, - _ => () + _ => (), } } diff --git a/capnp-rpc/examples/hello-world/server.rs b/capnp-rpc/examples/hello-world/server.rs index 98e3a4aaf..63d7efcc2 100644 --- a/capnp-rpc/examples/hello-world/server.rs +++ b/capnp-rpc/examples/hello-world/server.rs @@ -24,7 +24,7 @@ use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, RpcSystem}; use crate::hello_world_capnp::hello_world; -use futures::{AsyncReadExt}; +use futures::AsyncReadExt; use std::net::ToSocketAddrs; struct HelloWorldImpl; @@ -35,7 +35,6 @@ impl hello_world::Server for HelloWorldImpl { params: hello_world::SayHelloParams, mut results: hello_world::SayHelloResults, ) -> Promise<(), ::capnp::Error> { - let request = pry!(pry!(params.get()).get_request()); let name = pry!(request.get_name()); let message = format!("Hello, {}!", name); @@ -58,25 +57,28 @@ pub async fn main() -> Result<(), Box> { .next() .expect("could not parse address"); - tokio::task::LocalSet::new().run_until(async move { - let listener = tokio::net::TcpListener::bind(&addr).await?; - let hello_world_client: hello_world::Client = capnp_rpc::new_client(HelloWorldImpl); + tokio::task::LocalSet::new() + .run_until(async move { + let listener = tokio::net::TcpListener::bind(&addr).await?; + let hello_world_client: hello_world::Client = capnp_rpc::new_client(HelloWorldImpl); - loop { - let (stream, _) = listener.accept().await?; - stream.set_nodelay(true)?; - let (reader, writer) = tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); - let network = twoparty::VatNetwork::new( - reader, - writer, - rpc_twoparty_capnp::Side::Server, - Default::default(), - ); + loop { + let (stream, _) = listener.accept().await?; + stream.set_nodelay(true)?; + let (reader, writer) = + tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); + let network = twoparty::VatNetwork::new( + reader, + writer, + rpc_twoparty_capnp::Side::Server, + Default::default(), + ); - let rpc_system = - RpcSystem::new(Box::new(network), Some(hello_world_client.clone().client)); + let rpc_system = + RpcSystem::new(Box::new(network), Some(hello_world_client.clone().client)); - tokio::task::spawn_local(rpc_system); - } - }).await + tokio::task::spawn_local(rpc_system); + } + }) + .await } diff --git a/capnp-rpc/examples/pubsub/client.rs b/capnp-rpc/examples/pubsub/client.rs index 3e48098be..ae78fe3cf 100644 --- a/capnp-rpc/examples/pubsub/client.rs +++ b/capnp-rpc/examples/pubsub/client.rs @@ -19,21 +19,24 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use capnp_rpc::{RpcSystem, pry, twoparty, rpc_twoparty_capnp}; use crate::pubsub_capnp::{publisher, subscriber}; +use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, RpcSystem}; use capnp::capability::Promise; -use futures::{AsyncReadExt}; +use futures::AsyncReadExt; struct SubscriberImpl; impl subscriber::Server<::capnp::text::Owned> for SubscriberImpl { - fn push_message(&mut self, - params: subscriber::PushMessageParams<::capnp::text::Owned>, - _results: subscriber::PushMessageResults<::capnp::text::Owned>) - -> Promise<(), ::capnp::Error> - { - println!("message from publisher: {}", pry!(pry!(params.get()).get_message())); + fn push_message( + &mut self, + params: subscriber::PushMessageParams<::capnp::text::Owned>, + _results: subscriber::PushMessageResults<::capnp::text::Owned>, + ) -> Promise<(), ::capnp::Error> { + println!( + "message from publisher: {}", + pry!(pry!(params.get()).get_message()) + ); Promise::ok(()) } } @@ -46,26 +49,34 @@ pub async fn main() -> Result<(), Box> { return Ok(()); } - let addr = args[2].to_socket_addrs()?.next().expect("could not parse address"); + let addr = args[2] + .to_socket_addrs()? + .next() + .expect("could not parse address"); - tokio::task::LocalSet::new().run_until(async move { - let stream = tokio::net::TcpStream::connect(&addr).await?; - stream.set_nodelay(true)?; - let (reader, writer) = tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); - let rpc_network = - Box::new(twoparty::VatNetwork::new(reader, writer, - rpc_twoparty_capnp::Side::Client, - Default::default())); - let mut rpc_system = RpcSystem::new(rpc_network, None); - let publisher: publisher::Client<::capnp::text::Owned> = - rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); - let sub = capnp_rpc::new_client(SubscriberImpl); + tokio::task::LocalSet::new() + .run_until(async move { + let stream = tokio::net::TcpStream::connect(&addr).await?; + stream.set_nodelay(true)?; + let (reader, writer) = + tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); + let rpc_network = Box::new(twoparty::VatNetwork::new( + reader, + writer, + rpc_twoparty_capnp::Side::Client, + Default::default(), + )); + let mut rpc_system = RpcSystem::new(rpc_network, None); + let publisher: publisher::Client<::capnp::text::Owned> = + rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); + let sub = capnp_rpc::new_client(SubscriberImpl); - let mut request = publisher.subscribe_request(); - request.get().set_subscriber(sub); + let mut request = publisher.subscribe_request(); + request.get().set_subscriber(sub); - // Need to make sure not to drop the returned subscription object. - futures::future::try_join(rpc_system, request.send().promise).await?; - Ok(()) - }).await + // Need to make sure not to drop the returned subscription object. + futures::future::try_join(rpc_system, request.send().promise).await?; + Ok(()) + }) + .await } diff --git a/capnp-rpc/examples/pubsub/main.rs b/capnp-rpc/examples/pubsub/main.rs index bc8c3007b..28680cd74 100644 --- a/capnp-rpc/examples/pubsub/main.rs +++ b/capnp-rpc/examples/pubsub/main.rs @@ -20,7 +20,7 @@ // THE SOFTWARE. pub mod pubsub_capnp { - include!(concat!(env!("OUT_DIR"), "/pubsub_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/pubsub_capnp.rs")); } pub mod client; @@ -33,7 +33,7 @@ async fn main() -> Result<(), Box> { match &args[1][..] { "client" => return client::main().await, "server" => return server::main().await, - _ => () + _ => (), } } diff --git a/capnp-rpc/examples/pubsub/server.rs b/capnp-rpc/examples/pubsub/server.rs index 6426fc5d9..9f65e4dc1 100644 --- a/capnp-rpc/examples/pubsub/server.rs +++ b/capnp-rpc/examples/pubsub/server.rs @@ -19,12 +19,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use std::rc::Rc; use std::cell::RefCell; use std::collections::HashMap; +use std::rc::Rc; -use capnp_rpc::{RpcSystem, pry, twoparty, rpc_twoparty_capnp}; use crate::pubsub_capnp::{publisher, subscriber, subscription}; +use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, RpcSystem}; use capnp::capability::Promise; @@ -41,7 +41,9 @@ struct SubscriberMap { impl SubscriberMap { fn new() -> SubscriberMap { - SubscriberMap { subscribers: HashMap::new() } + SubscriberMap { + subscribers: HashMap::new(), + } } } @@ -52,7 +54,10 @@ struct SubscriptionImpl { impl SubscriptionImpl { fn new(id: u64, subscribers: Rc>) -> SubscriptionImpl { - SubscriptionImpl { id: id, subscribers: subscribers } + SubscriptionImpl { + id: id, + subscribers: subscribers, + } } } @@ -73,28 +78,37 @@ struct PublisherImpl { impl PublisherImpl { pub fn new() -> (PublisherImpl, Rc>) { let subscribers = Rc::new(RefCell::new(SubscriberMap::new())); - (PublisherImpl { next_id: 0, subscribers: subscribers.clone() }, - subscribers.clone()) + ( + PublisherImpl { + next_id: 0, + subscribers: subscribers.clone(), + }, + subscribers.clone(), + ) } } impl publisher::Server<::capnp::text::Owned> for PublisherImpl { - fn subscribe(&mut self, - params: publisher::SubscribeParams<::capnp::text::Owned>, - mut results: publisher::SubscribeResults<::capnp::text::Owned>,) - -> Promise<(), ::capnp::Error> - { + fn subscribe( + &mut self, + params: publisher::SubscribeParams<::capnp::text::Owned>, + mut results: publisher::SubscribeResults<::capnp::text::Owned>, + ) -> Promise<(), ::capnp::Error> { println!("subscribe"); self.subscribers.borrow_mut().subscribers.insert( self.next_id, SubscriberHandle { client: pry!(pry!(params.get()).get_subscriber()), requests_in_flight: 0, - } + }, ); - results.get().set_subscription(capnp_rpc::new_client( - SubscriptionImpl::new(self.next_id, self.subscribers.clone()))); + results + .get() + .set_subscription(capnp_rpc::new_client(SubscriptionImpl::new( + self.next_id, + self.subscribers.clone(), + ))); self.next_id += 1; Promise::ok(()) @@ -109,67 +123,79 @@ pub async fn main() -> Result<(), Box> { return Ok(()); } - let addr = args[2].to_socket_addrs()?.next().expect("could not parse address"); - - tokio::task::LocalSet::new().run_until(async move { - let listener = tokio::net::TcpListener::bind(&addr).await?; - let (publisher_impl, subscribers) = PublisherImpl::new(); - let publisher: publisher::Client<_> = capnp_rpc::new_client(publisher_impl); - - let handle_incoming = async move { - loop { - let (stream, _) = listener.accept().await?; - stream.set_nodelay(true)?; - let (reader, writer) = tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); - let network = - twoparty::VatNetwork::new(reader, writer, - rpc_twoparty_capnp::Side::Server, Default::default()); - let rpc_system = RpcSystem::new(Box::new(network), Some(publisher.clone().client)); - - tokio::task::spawn_local(rpc_system); - } - }; - - // Trigger sending approximately once per second. - let (tx, mut rx) = futures::channel::mpsc::unbounded::<()>(); - std::thread::spawn(move || { - while let Ok(()) = tx.unbounded_send(()) { - std::thread::sleep(std::time::Duration::from_millis(1000)); - } - }); - - let send_to_subscribers = async move { - while let Some(()) = rx.next().await { - let subscribers1 = subscribers.clone(); - let subs = &mut subscribers.borrow_mut().subscribers; - for (&idx, mut subscriber) in subs.iter_mut() { - if subscriber.requests_in_flight < 5 { - subscriber.requests_in_flight += 1; - let mut request = subscriber.client.push_message_request(); - request.get().set_message( + let addr = args[2] + .to_socket_addrs()? + .next() + .expect("could not parse address"); + + tokio::task::LocalSet::new() + .run_until(async move { + let listener = tokio::net::TcpListener::bind(&addr).await?; + let (publisher_impl, subscribers) = PublisherImpl::new(); + let publisher: publisher::Client<_> = capnp_rpc::new_client(publisher_impl); + + let handle_incoming = async move { + loop { + let (stream, _) = listener.accept().await?; + stream.set_nodelay(true)?; + let (reader, writer) = + tokio_util::compat::TokioAsyncReadCompatExt::compat(stream).split(); + let network = twoparty::VatNetwork::new( + reader, + writer, + rpc_twoparty_capnp::Side::Server, + Default::default(), + ); + let rpc_system = + RpcSystem::new(Box::new(network), Some(publisher.clone().client)); + + tokio::task::spawn_local(rpc_system); + } + }; + + // Trigger sending approximately once per second. + let (tx, mut rx) = futures::channel::mpsc::unbounded::<()>(); + std::thread::spawn(move || { + while let Ok(()) = tx.unbounded_send(()) { + std::thread::sleep(std::time::Duration::from_millis(1000)); + } + }); + + let send_to_subscribers = async move { + while let Some(()) = rx.next().await { + let subscribers1 = subscribers.clone(); + let subs = &mut subscribers.borrow_mut().subscribers; + for (&idx, mut subscriber) in subs.iter_mut() { + if subscriber.requests_in_flight < 5 { + subscriber.requests_in_flight += 1; + let mut request = subscriber.client.push_message_request(); + request.get().set_message( &format!("system time is: {:?}", ::std::time::SystemTime::now())[..])?; - let subscribers2 = subscribers1.clone(); - tokio::task::spawn_local( - request.send().promise.map(move |r| { - match r { + let subscribers2 = subscribers1.clone(); + tokio::task::spawn_local(request.send().promise.map( + move |r| match r { Ok(_) => { - subscribers2.borrow_mut().subscribers.get_mut(&idx).map(|ref mut s| { - s.requests_in_flight -= 1; - }); + subscribers2.borrow_mut().subscribers.get_mut(&idx).map( + |ref mut s| { + s.requests_in_flight -= 1; + }, + ); } Err(e) => { println!("Got error: {:?}. Dropping subscriber.", e); subscribers2.borrow_mut().subscribers.remove(&idx); } - } - })); + }, + )); + } } } - } - Ok::<(), Box>(()) - }; - - let _ : ((), ()) = futures::future::try_join(handle_incoming, send_to_subscribers).await?; - Ok(()) - }).await + Ok::<(), Box>(()) + }; + + let _: ((), ()) = + futures::future::try_join(handle_incoming, send_to_subscribers).await?; + Ok(()) + }) + .await } diff --git a/capnp-rpc/src/attach.rs b/capnp-rpc/src/attach.rs index 0cf6c138d..d89144862 100644 --- a/capnp-rpc/src/attach.rs +++ b/capnp-rpc/src/attach.rs @@ -18,19 +18,23 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +use futures::Future; use std::pin::Pin; use std::task::{Context, Poll}; -use futures::{Future}; -pub struct AttachFuture where F: Future + Unpin { +pub struct AttachFuture +where + F: Future + Unpin, +{ original_future: F, value: Option, } -impl Unpin for AttachFuture where F: Future + Unpin {} +impl Unpin for AttachFuture where F: Future + Unpin {} -impl Future for AttachFuture - where F: Future + Unpin, +impl Future for AttachFuture +where + F: Future + Unpin, { type Output = F::Output; @@ -43,9 +47,13 @@ impl Future for AttachFuture } } -pub trait Attach: Future where Self: Unpin { +pub trait Attach: Future +where + Self: Unpin, +{ fn attach(self, value: T) -> AttachFuture - where Self: Sized + where + Self: Sized, { AttachFuture { original_future: self, @@ -54,4 +62,4 @@ pub trait Attach: Future where Self: Unpin { } } -impl Attach for F where F: Future + Unpin {} +impl Attach for F where F: Future + Unpin {} diff --git a/capnp-rpc/src/broken.rs b/capnp-rpc/src/broken.rs index 773eb58f4..01100981b 100644 --- a/capnp-rpc/src/broken.rs +++ b/capnp-rpc/src/broken.rs @@ -19,15 +19,16 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use capnp::{any_pointer}; +use capnp::any_pointer; +use capnp::private::capability::{ + ClientHook, ParamsHook, PipelineHook, PipelineOp, RequestHook, ResultsHook, +}; use capnp::Error; -use capnp::private::capability::{ClientHook, ParamsHook, PipelineHook, PipelineOp, - RequestHook, ResultsHook}; use capnp::capability::{Promise, RemotePromise}; -use capnp::traits::{ImbueMut}; +use capnp::traits::ImbueMut; -use std::rc::{Rc}; +use std::rc::Rc; pub struct Pipeline { error: Error, @@ -80,9 +81,7 @@ impl RequestHook for Request { pipeline: any_pointer::Pipeline::new(Box::new(pipeline)), } } - fn tail_send(self: Box) - -> Option<(u32, Promise<(), Error>, Box)> - { + fn tail_send(self: Box) -> Option<(u32, Promise<(), Error>, Box)> { None } } @@ -111,24 +110,34 @@ impl Client { impl ClientHook for Client { fn add_ref(&self) -> Box { - Box::new(Client { inner: self.inner.clone() } ) - } - fn new_call(&self, _interface_id: u64, _method_id: u16, - size_hint: Option<::capnp::MessageSize>) - -> ::capnp::capability::Request - { - ::capnp::capability::Request::new( - Box::new(Request::new(self.inner.error.clone(), size_hint))) - } - - fn call(&self, _interface_id: u64, _method_id: u16, _params: Box, _results: Box) - -> Promise<(), Error> - { + Box::new(Client { + inner: self.inner.clone(), + }) + } + fn new_call( + &self, + _interface_id: u64, + _method_id: u16, + size_hint: Option<::capnp::MessageSize>, + ) -> ::capnp::capability::Request { + ::capnp::capability::Request::new(Box::new(Request::new( + self.inner.error.clone(), + size_hint, + ))) + } + + fn call( + &self, + _interface_id: u64, + _method_id: u16, + _params: Box, + _results: Box, + ) -> Promise<(), Error> { Promise::err(self.inner.error.clone()) } fn get_ptr(&self) -> usize { - (self.inner.as_ref()) as * const _ as usize + (self.inner.as_ref()) as *const _ as usize } fn get_brand(&self) -> usize { diff --git a/capnp-rpc/src/lib.rs b/capnp-rpc/src/lib.rs index 6ed235254..62ef908d9 100644 --- a/capnp-rpc/src/lib.rs +++ b/capnp-rpc/src/lib.rs @@ -58,19 +58,18 @@ //! //! For a more complete example, see - +use capnp::capability::Promise; +use capnp::private::capability::ClientHook; +use capnp::Error; +use futures::channel::oneshot; +use futures::{Future, FutureExt, TryFutureExt}; +use std::cell::RefCell; use std::pin::Pin; +use std::rc::Rc; use std::task::{Context, Poll}; -use futures::{Future, FutureExt, TryFutureExt}; -use futures::channel::oneshot; -use capnp::Error; -use capnp::capability::Promise; -use capnp::private::capability::{ClientHook}; -use std::cell::{RefCell}; -use std::rc::{Rc}; -use crate::task_set::TaskSet; pub use crate::rpc::Disconnector; +use crate::task_set::TaskSet; /// Code generated from /// [rpc.capnp](https://github.com/sandstorm-io/capnproto/blob/master/c%2B%2B/src/capnp/rpc.capnp). @@ -86,20 +85,21 @@ pub mod rpc_twoparty_capnp; /// enclosing function with `Promise::err(e)`. #[macro_export] macro_rules! pry { - ($expr:expr) => ( + ($expr:expr) => { match $expr { ::std::result::Result::Ok(val) => val, ::std::result::Result::Err(err) => { return ::capnp::capability::Promise::err(::std::convert::From::from(err)) } - }) + } + }; } +mod attach; mod broken; mod local; mod queued; mod rpc; -mod attach; mod sender_queue; mod split; mod task_set; @@ -111,9 +111,12 @@ pub trait OutgoingMessage { /// Sends the message. Returns a promise for the message that resolves once the send has completed. /// Dropping the returned promise does *not* cancel the send. - fn send(self: Box) - -> (Promise>, ::capnp::Error>, - Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>); + fn send( + self: Box, + ) -> ( + Promise>, ::capnp::Error>, + Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, + ); fn take(self: Box) -> ::capnp::message::Builder<::capnp::message::HeapAllocator>; } @@ -159,7 +162,10 @@ pub trait VatNetwork { /// An `RpcSystem` is a `Future` and needs to be driven by a task executor. A common way /// accomplish that is to pass the `RpcSystem` to `tokio_core::reactor::Handle::spawn()`. #[must_use = "futures do nothing unless polled"] -pub struct RpcSystem where VatId: 'static { +pub struct RpcSystem +where + VatId: 'static, +{ network: Box>, bootstrap_cap: Box, @@ -169,15 +175,15 @@ pub struct RpcSystem where VatId: 'static { connection_state: Rc>>>>, tasks: TaskSet, - handle: crate::task_set::TaskSetHandle + handle: crate::task_set::TaskSetHandle, } -impl RpcSystem { +impl RpcSystem { /// Constructs a new `RpcSystem` with the given network and bootstrap capability. pub fn new( mut network: Box>, - bootstrap: Option<::capnp::capability::Client>) -> RpcSystem - { + bootstrap: Option<::capnp::capability::Client>, + ) -> RpcSystem { let bootstrap_cap = match bootstrap { Some(cap) => cap.hook, None => broken::new_cap(Error::failed("no bootstrap capability".to_string())), @@ -211,7 +217,6 @@ impl RpcSystem { handle: handle.clone(), }; - let accept_loop = result.accept_loop(); handle.add(accept_loop); result @@ -219,7 +224,8 @@ impl RpcSystem { /// Connects to the given vat and returns its bootstrap interface. pub fn bootstrap(&mut self, vat_id: VatId) -> T - where T: ::capnp::capability::FromClientHook + where + T: ::capnp::capability::FromClientHook, { let connection = match self.network.connect(vat_id) { Some(connection) => connection, @@ -227,10 +233,12 @@ impl RpcSystem { return T::new(self.bootstrap_cap.clone()); } }; - let connection_state = - RpcSystem::get_connection_state(self.connection_state.clone(), - self.bootstrap_cap.clone(), - connection, self.handle.clone()); + let connection_state = RpcSystem::get_connection_state( + self.connection_state.clone(), + self.bootstrap_cap.clone(), + connection, + self.handle.clone(), + ); let hook = rpc::ConnectionState::bootstrap(connection_state.clone()); T::new(hook) @@ -242,10 +250,12 @@ impl RpcSystem { let bootstrap_cap = self.bootstrap_cap.clone(); let handle = self.handle.clone(); Promise::from_future(self.network.accept().map_ok(move |connection| { - RpcSystem::get_connection_state(connection_state_ref, - bootstrap_cap, - connection, - handle); + RpcSystem::get_connection_state( + connection_state_ref, + bootstrap_cap, + connection, + handle, + ); })) } @@ -253,17 +263,17 @@ impl RpcSystem { // `ConnectionState` built from a local bootstrap capability and `connection`, // spawning any background tasks onto `handle`. Returns the resulting value // held in `connection_state_ref`. - fn get_connection_state(connection_state_ref: Rc>>>>, - bootstrap_cap: Box, - connection: Box>, - mut handle: crate::task_set::TaskSetHandle) - -> Rc> - { + fn get_connection_state( + connection_state_ref: Rc>>>>, + bootstrap_cap: Box, + connection: Box>, + mut handle: crate::task_set::TaskSetHandle, + ) -> Rc> { // TODO this needs to be updated once we allow more general VatNetworks. let (tasks, result) = match *connection_state_ref.borrow() { Some(ref connection_state) => { // return early. - return connection_state.clone() + return connection_state.clone(); } None => { let (on_disconnect_fulfiller, on_disconnect_promise) = @@ -291,54 +301,64 @@ impl RpcSystem { } } -impl Future for RpcSystem where VatId: 'static { - type Output = Result<(),Error>; +impl Future for RpcSystem +where + VatId: 'static, +{ + type Output = Result<(), Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { Pin::new(&mut self.tasks).poll(cx) } } /// Creates a new local RPC client of type `C` out of an object that implements a server trait `S`. -pub fn new_client(s: S) -> C where C: capnp::capability::FromServer { - capnp::capability::FromClientHook::new(Box::new( - local::Client::new(>::from_server(s)))) +pub fn new_client(s: S) -> C +where + C: capnp::capability::FromServer, +{ + capnp::capability::FromClientHook::new(Box::new(local::Client::new( + >::from_server(s), + ))) } /// Allows a server to recognize its own capabilities when passed back to it, and obtain the /// underlying Server objects associated with them. -pub struct CapabilityServerSet - where C: capnp::capability::FromServer +pub struct CapabilityServerSet +where + C: capnp::capability::FromServer, { caps: std::collections::HashMap>>, } -impl CapabilityServerSet - where C: capnp::capability::FromServer +impl CapabilityServerSet +where + C: capnp::capability::FromServer, { pub fn new() -> Self { - Self { caps: std::default::Default::default() } + Self { + caps: std::default::Default::default(), + } } /// Adds a new capability to the set and returns a client backed by it. pub fn new_client(&mut self, s: S) -> C { - let dispatch = - >::from_server(s); + let dispatch = >::from_server(s); let wrapped = Rc::new(RefCell::new(dispatch)); let ptr = wrapped.as_ptr() as usize; self.caps.insert(ptr, wrapped.clone()); - capnp::capability::FromClientHook::new(Box::new( - local::Client::from_rc(wrapped))) + capnp::capability::FromClientHook::new(Box::new(local::Client::from_rc(wrapped))) } /// Looks up a capability and returns its underlying server object, if found. /// Fully resolves the capability before looking it up. - pub async fn get_local_server(&self, - client: &C) - -> Option<&Rc>> - where C: capnp::capability::FromClientHook + pub async fn get_local_server(&self, client: &C) -> Option<&Rc>> + where + C: capnp::capability::FromClientHook, { let resolved: C = capnp::capability::get_resolved_cap( - capnp::capability::FromClientHook::new(client.as_client_hook().add_ref())).await; + capnp::capability::FromClientHook::new(client.as_client_hook().add_ref()), + ) + .await; let hook = resolved.into_client_hook(); let ptr = hook.get_ptr(); self.caps.get(&ptr) @@ -349,10 +369,9 @@ impl CapabilityServerSet /// to call `get_resolved_cap()` before calling this. The advantage of this method /// over `get_local_server()` is that this one is synchronous and borrows `self` /// over a shorter span (which can be very important if `self` is inside a `RefCell`). - pub fn get_local_server_of_resolved(&self, - client: &C) - -> Option<&Rc>> - where C: capnp::capability::FromClientHook + pub fn get_local_server_of_resolved(&self, client: &C) -> Option<&Rc>> + where + C: capnp::capability::FromClientHook, { let hook = client.as_client_hook(); let ptr = hook.get_ptr(); @@ -364,9 +383,10 @@ impl CapabilityServerSet /// before the promise resolves. // TODO: figure out a better way to allow construction of promise clients. pub fn new_promise_client(client_promise: F) -> T - where T: ::capnp::capability::FromClientHook, - F: ::futures::Future>, - F: 'static + Unpin +where + T: ::capnp::capability::FromClientHook, + F: ::futures::Future>, + F: 'static + Unpin, { let mut queued_client = crate::queued::Client::new(None); let weak_client = Rc::downgrade(&queued_client.inner); @@ -388,12 +408,18 @@ impl crate::task_set::TaskReaper for SystemTaskReaper { } } -pub struct ImbuedMessageBuilder where A: ::capnp::message::Allocator { +pub struct ImbuedMessageBuilder +where + A: ::capnp::message::Allocator, +{ builder: ::capnp::message::Builder, cap_table: Vec>>, } -impl ImbuedMessageBuilder where A: ::capnp::message::Allocator { +impl ImbuedMessageBuilder +where + A: ::capnp::message::Allocator, +{ pub fn new(allocator: A) -> Self { ImbuedMessageBuilder { builder: ::capnp::message::Builder::new(allocator), @@ -402,7 +428,8 @@ impl ImbuedMessageBuilder where A: ::capnp::message::Allocator { } pub fn get_root<'a, T>(&'a mut self) -> ::capnp::Result - where T: ::capnp::traits::FromPointerBuilder<'a> + where + T: ::capnp::traits::FromPointerBuilder<'a>, { use capnp::traits::ImbueMut; let mut root: ::capnp::any_pointer::Builder = self.builder.get_root()?; @@ -411,7 +438,8 @@ impl ImbuedMessageBuilder where A: ::capnp::message::Allocator { } pub fn set_root(&mut self, value: From) -> ::capnp::Result<()> - where From: ::capnp::traits::SetPointerBuilder + where + From: ::capnp::traits::SetPointerBuilder, { use capnp::traits::ImbueMut; let mut root: ::capnp::any_pointer::Builder = self.builder.get_root()?; @@ -421,5 +449,5 @@ impl ImbuedMessageBuilder where A: ::capnp::message::Allocator { } fn canceled_to_error(_e: futures::channel::oneshot::Canceled) -> Error { - Error::failed(format!("oneshot was canceled")) + Error::failed(format!("oneshot was canceled")) } diff --git a/capnp-rpc/src/local.rs b/capnp-rpc/src/local.rs index fb3a202c9..107ba306f 100644 --- a/capnp-rpc/src/local.rs +++ b/capnp-rpc/src/local.rs @@ -18,19 +18,20 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use capnp::{any_pointer, message}; -use capnp::Error; -use capnp::traits::{Imbue, ImbueMut}; use capnp::capability::{self, Promise}; -use capnp::private::capability::{ClientHook, ParamsHook, PipelineHook, PipelineOp, - RequestHook, ResponseHook, ResultsHook}; +use capnp::private::capability::{ + ClientHook, ParamsHook, PipelineHook, PipelineOp, RequestHook, ResponseHook, ResultsHook, +}; +use capnp::traits::{Imbue, ImbueMut}; +use capnp::Error; +use capnp::{any_pointer, message}; -use futures::{TryFutureExt}; use futures::channel::oneshot; +use futures::TryFutureExt; use std::cell::RefCell; -use std::rc::{Rc}; use std::mem; +use std::rc::Rc; pub trait ResultsDoneHook { fn add_ref(&self) -> Box; @@ -44,14 +45,12 @@ impl Clone for Box { } pub struct Response { - results: Box + results: Box, } impl Response { fn new(results: Box) -> Response { - Response { - results - } + Response { results } } } @@ -67,14 +66,11 @@ struct Params { } impl Params { - fn new(request: message::Builder, - cap_table: Vec>>) - -> Params - { - Params { - request, - cap_table, - } + fn new( + request: message::Builder, + cap_table: Vec>>, + ) -> Params { + Params { request, cap_table } } } @@ -104,7 +100,9 @@ impl Results { impl Drop for Results { fn drop(&mut self) { - if let (Some(message), Some(fulfiller)) = (self.message.take(), self.results_done_fulfiller.take()) { + if let (Some(message), Some(fulfiller)) = + (self.message.take(), self.results_done_fulfiller.take()) + { let cap_table = mem::replace(&mut self.cap_table, Vec::new()); let _ = fulfiller.send(Box::new(ResultsDone::new(message, cap_table))); } else { @@ -116,7 +114,11 @@ impl Drop for Results { impl ResultsHook for Results { fn get(&mut self) -> ::capnp::Result { match *self { - Results { message: Some(ref mut message), ref mut cap_table, .. } => { + Results { + message: Some(ref mut message), + ref mut cap_table, + .. + } => { let mut result: any_pointer::Builder = message.get_root()?; result.imbue_mut(cap_table); Ok(result) @@ -129,9 +131,10 @@ impl ResultsHook for Results { unimplemented!() } - fn direct_tail_call(self: Box, _request: Box) - -> (Promise<(), Error>, Box) - { + fn direct_tail_call( + self: Box, + _request: Box, + ) -> (Promise<(), Error>, Box) { unimplemented!() } @@ -150,23 +153,21 @@ struct ResultsDone { } impl ResultsDone { - fn new(message: message::Builder, - cap_table: Vec>>, - ) - -> ResultsDone - { + fn new( + message: message::Builder, + cap_table: Vec>>, + ) -> ResultsDone { ResultsDone { - inner: Rc::new(ResultsDoneInner { - message, - cap_table, - }), + inner: Rc::new(ResultsDoneInner { message, cap_table }), } } } impl ResultsDoneHook for ResultsDone { fn add_ref(&self) -> Box { - Box::new(ResultsDone { inner: self.inner.clone() }) + Box::new(ResultsDone { + inner: self.inner.clone(), + }) } fn get(&self) -> ::capnp::Result { let mut result: any_pointer::Reader = self.inner.message.get_root_as_reader()?; @@ -175,7 +176,6 @@ impl ResultsDoneHook for ResultsDone { } } - pub struct Request { message: message::Builder<::capnp::message::HeapAllocator>, cap_table: Vec>>, @@ -185,11 +185,12 @@ pub struct Request { } impl Request { - pub fn new(interface_id: u64, method_id: u16, - _size_hint: Option<::capnp::MessageSize>, - client: Box) - -> Request - { + pub fn new( + interface_id: u64, + method_id: u16, + _size_hint: Option<::capnp::MessageSize>, + client: Box, + ) -> Request { Request { message: message::Builder::new_default(), cap_table: Vec::new(), @@ -211,21 +212,34 @@ impl RequestHook for Request { } fn send(self: Box) -> capability::RemotePromise { let tmp = *self; - let Request { message, cap_table, interface_id, method_id, client } = tmp; + let Request { + message, + cap_table, + interface_id, + method_id, + client, + } = tmp; let params = Params::new(message, cap_table); - let (results_done_fulfiller, results_done_promise) = oneshot::channel::>(); + let (results_done_fulfiller, results_done_promise) = + oneshot::channel::>(); let results_done_promise = results_done_promise.map_err(crate::canceled_to_error); let results = Results::new(results_done_fulfiller); let promise = client.call(interface_id, method_id, Box::new(params), Box::new(results)); - let (pipeline_sender, mut pipeline) = crate::queued::Pipeline::new(); - let p = futures::future::try_join(promise, results_done_promise).and_then(move |((), results_done_hook)| { - pipeline_sender.complete(Box::new(Pipeline::new(results_done_hook.add_ref())) as Box); - Promise::ok((capability::Response::new(Box::new(Response::new(results_done_hook))), ())) - }); + let p = futures::future::try_join(promise, results_done_promise).and_then( + move |((), results_done_hook)| { + pipeline_sender + .complete(Box::new(Pipeline::new(results_done_hook.add_ref())) + as Box); + Promise::ok(( + capability::Response::new(Box::new(Response::new(results_done_hook))), + (), + )) + }, + ); let (left, right) = crate::split::split(p); @@ -237,9 +251,7 @@ impl RequestHook for Request { pipeline, } } - fn tail_send(self: Box) - -> Option<(u32, Promise<(), Error>, Box)> - { + fn tail_send(self: Box) -> Option<(u32, Promise<(), Error>, Box)> { unimplemented!() } } @@ -255,14 +267,16 @@ pub struct Pipeline { impl Pipeline { pub fn new(results: Box) -> Pipeline { Pipeline { - inner: Rc::new(RefCell::new(PipelineInner { results })) + inner: Rc::new(RefCell::new(PipelineInner { results })), } } } impl Clone for Pipeline { fn clone(&self) -> Pipeline { - Pipeline { inner: self.inner.clone() } + Pipeline { + inner: self.inner.clone(), + } } } @@ -271,21 +285,34 @@ impl PipelineHook for Pipeline { Box::new(self.clone()) } fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box { - match self.inner.borrow_mut().results.get().unwrap().get_pipelined_cap(ops) { + match self + .inner + .borrow_mut() + .results + .get() + .unwrap() + .get_pipelined_cap(ops) + { Ok(v) => v, Err(e) => Box::new(crate::broken::Client::new(e, true, 0)) as Box, } } } -pub struct Client where S: capability::Server { +pub struct Client +where + S: capability::Server, +{ inner: Rc>, } -impl Client where S: capability::Server { +impl Client +where + S: capability::Server, +{ pub fn new(server: S) -> Client { Client { - inner: Rc::new(RefCell::new(server)) + inner: Rc::new(RefCell::new(server)), } } @@ -294,27 +321,45 @@ impl Client where S: capability::Server { } } -impl Clone for Client where S: capability::Server { +impl Clone for Client +where + S: capability::Server, +{ fn clone(&self) -> Client { - Client { inner: self.inner.clone() } + Client { + inner: self.inner.clone(), + } } } -impl ClientHook for Client where S: capability::Server + 'static { +impl ClientHook for Client +where + S: capability::Server + 'static, +{ fn add_ref(&self) -> Box { Box::new(self.clone()) } - fn new_call(&self, interface_id: u64, method_id: u16, - size_hint: Option<::capnp::MessageSize>) - -> capability::Request - { - capability::Request::new( - Box::new(Request::new(interface_id, method_id, size_hint, self.add_ref()))) - } - - fn call(&self, interface_id: u64, method_id: u16, params: Box, results: Box) - -> Promise<(), Error> - { + fn new_call( + &self, + interface_id: u64, + method_id: u16, + size_hint: Option<::capnp::MessageSize>, + ) -> capability::Request { + capability::Request::new(Box::new(Request::new( + interface_id, + method_id, + size_hint, + self.add_ref(), + ))) + } + + fn call( + &self, + interface_id: u64, + method_id: u16, + params: Box, + results: Box, + ) -> Promise<(), Error> { // We don't want to actually dispatch the call synchronously, because we don't want the callee // to have any side effects before the promise is returned to the caller. This helps avoid // race conditions. @@ -327,9 +372,12 @@ impl ClientHook for Client where S: capability::Server + 'static { // We put this borrow_mut() inside a block to avoid a potential // double borrow during f.await let server = &mut *inner.borrow_mut(); - server.dispatch_call(interface_id, method_id, - ::capnp::capability::Params::new(params), - ::capnp::capability::Results::new(results)) + server.dispatch_call( + interface_id, + method_id, + ::capnp::capability::Params::new(params), + ::capnp::capability::Results::new(results), + ) }; f.await }) diff --git a/capnp-rpc/src/queued.rs b/capnp-rpc/src/queued.rs index 434e5e65d..f5e3a5d65 100644 --- a/capnp-rpc/src/queued.rs +++ b/capnp-rpc/src/queued.rs @@ -19,20 +19,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use capnp::{any_pointer}; -use capnp::Error; +use capnp::any_pointer; use capnp::capability::Promise; -use capnp::private::capability::{ClientHook, ParamsHook, PipelineHook, PipelineOp, - ResultsHook}; +use capnp::private::capability::{ClientHook, ParamsHook, PipelineHook, PipelineOp, ResultsHook}; +use capnp::Error; use futures::{Future, FutureExt, TryFutureExt}; use std::cell::RefCell; use std::rc::{Rc, Weak}; -use crate::{broken, local}; use crate::attach::Attach; use crate::sender_queue::SenderQueue; +use crate::{broken, local}; pub struct PipelineInner { // Once the promise resolves, this will become non-null and point to the underlying object. @@ -75,8 +74,10 @@ impl Drop for PipelineInnerSender { if let Some(pipeline_inner) = weak_queued.upgrade() { PipelineInner::resolve( &pipeline_inner, - Ok(Box::new( - crate::broken::Pipeline::new(Error::failed("PipelineInnerSender was canceled".into()))))); + Ok(Box::new(crate::broken::Pipeline::new(Error::failed( + "PipelineInnerSender was canceled".into(), + )))), + ); } } } @@ -104,22 +105,32 @@ impl Pipeline { clients_to_resolve: SenderQueue::new(), })); - - (PipelineInnerSender { inner: Some(Rc::downgrade(&inner)) }, Pipeline { inner }) + ( + PipelineInnerSender { + inner: Some(Rc::downgrade(&inner)), + }, + Pipeline { inner }, + ) } pub fn drive(&mut self, promise: F) - where F: Future> + 'static + Unpin + where + F: Future> + 'static + Unpin, { - let new = - Promise::from_future(futures::future::try_join(self.inner.borrow_mut().promise_to_drive.clone(),promise).map_ok(|_|())).shared(); + let new = Promise::from_future( + futures::future::try_join(self.inner.borrow_mut().promise_to_drive.clone(), promise) + .map_ok(|_| ()), + ) + .shared(); self.inner.borrow_mut().promise_to_drive = new; } } impl Clone for Pipeline { fn clone(&self) -> Pipeline { - Pipeline { inner: self.inner.clone() } + Pipeline { + inner: self.inner.clone(), + } } } @@ -133,13 +144,16 @@ impl PipelineHook for Pipeline { fn get_pipelined_cap_move(&self, ops: Vec) -> Box { if let Some(ref p) = self.inner.borrow().redirect { - return p.get_pipelined_cap_move(ops) + return p.get_pipelined_cap_move(ops); } let mut queued_client = Client::new(Some(self.inner.clone())); queued_client.drive(self.inner.borrow().promise_to_drive.clone()); let weak_queued = Rc::downgrade(&queued_client.inner); - self.inner.borrow_mut().clients_to_resolve.push_detach((weak_queued, ops)); + self.inner + .borrow_mut() + .clients_to_resolve + .push_detach((weak_queued, ops)); Box::new(queued_client) } @@ -158,8 +172,8 @@ pub struct ClientInner { // When this promise resolves, each queued call will be forwarded to the real client. This needs // to occur *before* any 'whenMoreResolved()' promises resolve, because we want to make sure // previously-queued calls are delivered before any new calls made in response to the resolution. - call_forwarding_queue: SenderQueue<(u64, u16, Box, Box), - Promise<(), Error>>, + call_forwarding_queue: + SenderQueue<(u64, u16, Box, Box), Promise<(), Error>>, // whenMoreResolved() returns forks of this promise. These must resolve *after* queued calls // have been initiated (so that any calls made in the whenMoreResolved() handler are correctly @@ -197,8 +211,7 @@ pub struct Client { } impl Client { - pub fn new(pipeline_inner: Option>>) -> Client - { + pub fn new(pipeline_inner: Option>>) -> Client { let inner = Rc::new(RefCell::new(ClientInner { promise_to_drive: None, pipeline_inner, @@ -210,7 +223,8 @@ impl Client { } pub fn drive(&mut self, promise: F) - where F: Future> + 'static + Unpin + where + F: Future> + 'static + Unpin, { assert!(self.inner.borrow().promise_to_drive.is_none()); self.inner.borrow_mut().promise_to_drive = Some(Promise::from_future(promise).shared()); @@ -219,35 +233,54 @@ impl Client { impl ClientHook for Client { fn add_ref(&self) -> Box { - Box::new(Client {inner: self.inner.clone()}) + Box::new(Client { + inner: self.inner.clone(), + }) } - fn new_call(&self, interface_id: u64, method_id: u16, - size_hint: Option<::capnp::MessageSize>) - -> ::capnp::capability::Request - { - ::capnp::capability::Request::new( - Box::new(local::Request::new(interface_id, method_id, size_hint, self.add_ref()))) + fn new_call( + &self, + interface_id: u64, + method_id: u16, + size_hint: Option<::capnp::MessageSize>, + ) -> ::capnp::capability::Request { + ::capnp::capability::Request::new(Box::new(local::Request::new( + interface_id, + method_id, + size_hint, + self.add_ref(), + ))) } - fn call(&self, interface_id: u64, method_id: u16, params: Box, results: Box) - -> Promise<(), Error> - { + fn call( + &self, + interface_id: u64, + method_id: u16, + params: Box, + results: Box, + ) -> Promise<(), Error> { if let Some(ref client) = self.inner.borrow().redirect { - return client.call(interface_id, method_id, params, results) + return client.call(interface_id, method_id, params, results); } let inner_clone = self.inner.clone(); - let promise = self.inner.borrow_mut().call_forwarding_queue.push( - (interface_id, method_id, params, results)).attach(inner_clone).and_then(|x| x); + let promise = self + .inner + .borrow_mut() + .call_forwarding_queue + .push((interface_id, method_id, params, results)) + .attach(inner_clone) + .and_then(|x| x); match self.inner.borrow().promise_to_drive { - Some(ref p) => Promise::from_future(futures::future::try_join(p.clone(),promise).map_ok(|v| v.1)), + Some(ref p) => { + Promise::from_future(futures::future::try_join(p.clone(), promise).map_ok(|v| v.1)) + } None => Promise::from_future(promise), } } fn get_ptr(&self) -> usize { - (&*self.inner.borrow()) as * const _ as usize + (&*self.inner.borrow()) as *const _ as usize } fn get_brand(&self) -> usize { @@ -256,12 +289,8 @@ impl ClientHook for Client { fn get_resolved(&self) -> Option> { match self.inner.borrow().redirect { - Some(ref inner) => { - Some(inner.clone()) - } - None => { - None - } + Some(ref inner) => Some(inner.clone()), + None => None, } } @@ -272,7 +301,9 @@ impl ClientHook for Client { let promise = self.inner.borrow_mut().client_resolution_queue.push(()); match self.inner.borrow().promise_to_drive { - Some(ref p) => Some(Promise::from_future(futures::future::try_join(p.clone(), promise).map_ok(|v| v.1))), + Some(ref p) => Some(Promise::from_future( + futures::future::try_join(p.clone(), promise).map_ok(|v| v.1), + )), None => Some(Promise::from_future(promise)), } } diff --git a/capnp-rpc/src/rpc.rs b/capnp-rpc/src/rpc.rs index d6d66afe2..b5a4ea17a 100644 --- a/capnp-rpc/src/rpc.rs +++ b/capnp-rpc/src/rpc.rs @@ -22,28 +22,31 @@ use std::pin::Pin; use std::task::{Context, Poll}; -use capnp::{any_pointer}; -use capnp::Error; +use capnp::any_pointer; use capnp::capability::Promise; -use capnp::private::capability::{ClientHook, ParamsHook, PipelineHook, PipelineOp, - RequestHook, ResponseHook, ResultsHook}; +use capnp::private::capability::{ + ClientHook, ParamsHook, PipelineHook, PipelineOp, RequestHook, ResponseHook, ResultsHook, +}; +use capnp::Error; -use futures::{future, Future, FutureExt, TryFutureExt}; use futures::channel::oneshot; +use futures::{future, Future, FutureExt, TryFutureExt}; -use std::vec::Vec; -use std::collections::hash_map::HashMap; -use std::collections::binary_heap::BinaryHeap; use std::cell::{Cell, RefCell}; +use std::collections::binary_heap::BinaryHeap; +use std::collections::hash_map::HashMap; use std::rc::{Rc, Weak}; +use std::vec::Vec; use std::{cmp, mem}; -use crate::rpc_capnp::{bootstrap, call, cap_descriptor, disembargo, exception, finish, - message, message_target, payload, resolve, return_, promised_answer}; use crate::attach::Attach; -use crate::{broken, local, queued}; use crate::local::ResultsDoneHook; +use crate::rpc_capnp::{ + bootstrap, call, cap_descriptor, disembargo, exception, finish, message, message_target, + payload, promised_answer, resolve, return_, +}; use crate::task_set::TaskSet; +use crate::{broken, local, queued}; pub type QuestionId = u32; pub type AnswerId = QuestionId; @@ -54,20 +57,28 @@ pub struct ImportTable { slots: HashMap, } -impl ImportTable { +impl ImportTable { pub fn new() -> ImportTable { - ImportTable { slots : HashMap::new() } + ImportTable { + slots: HashMap::new(), + } } } #[derive(PartialEq, Eq)] -struct ReverseU32 { val: u32 } +struct ReverseU32 { + val: u32, +} impl cmp::Ord for ReverseU32 { fn cmp(&self, other: &ReverseU32) -> cmp::Ordering { - if self.val > other.val { cmp::Ordering::Less } - else if self.val < other.val { cmp::Ordering::Greater } - else { cmp::Ordering::Equal } + if self.val > other.val { + cmp::Ordering::Less + } else if self.val < other.val { + cmp::Ordering::Greater + } else { + cmp::Ordering::Equal + } } } @@ -84,34 +95,42 @@ struct ExportTable { free_ids: BinaryHeap, } -struct ExportTableIter<'a, T> where T: 'a { +struct ExportTableIter<'a, T> +where + T: 'a, +{ table: &'a ExportTable, idx: usize, } -impl <'a, T> ::std::iter::Iterator for ExportTableIter<'a, T> where T: 'a{ +impl<'a, T> ::std::iter::Iterator for ExportTableIter<'a, T> +where + T: 'a, +{ type Item = &'a T; fn next(&mut self) -> Option<&'a T> { while self.idx < self.table.slots.len() { let idx = self.idx; self.idx += 1; if let Some(ref v) = self.table.slots[idx] { - return Some(v) + return Some(v); } } None } } -impl ExportTable { +impl ExportTable { pub fn new() -> ExportTable { - ExportTable { slots: Vec::new(), - free_ids: BinaryHeap::new() } + ExportTable { + slots: Vec::new(), + free_ids: BinaryHeap::new(), + } } pub fn erase(&mut self, id: u32) { self.slots[id as usize] = None; - self.free_ids.push(ReverseU32 { val: id } ); + self.free_ids.push(ReverseU32 { val: id }); } pub fn push(&mut self, val: T) -> u32 { @@ -142,12 +161,15 @@ impl ExportTable { pub fn iter(&self) -> ExportTableIter { ExportTableIter { table: self, - idx: 0 + idx: 0, } } } -struct Question where VatId: 'static { +struct Question +where + VatId: 'static, +{ is_awaiting_return: bool, #[allow(dead_code)] @@ -157,30 +179,42 @@ struct Question where VatId: 'static { is_tail_call: bool, /// The local QuestionRef, set to None when it is destroyed. - self_ref: Option>>> + self_ref: Option>>>, } -impl Question { +impl Question { fn new() -> Question { - Question { is_awaiting_return: true, param_exports: Vec::new(), - is_tail_call: false, self_ref: None } + Question { + is_awaiting_return: true, + param_exports: Vec::new(), + is_tail_call: false, + self_ref: None, + } } } /// A reference to an entry on the question table. Used to detect when the `Finish` message /// can be sent. -struct QuestionRef where VatId: 'static { +struct QuestionRef +where + VatId: 'static, +{ connection_state: Rc>, id: QuestionId, fulfiller: Option, Error>>>, } -impl QuestionRef { - fn new(state: Rc>, id: QuestionId, - fulfiller: oneshot::Sender, Error>>) - -> QuestionRef - { - QuestionRef { connection_state: state, id, fulfiller: Some(fulfiller) } +impl QuestionRef { + fn new( + state: Rc>, + id: QuestionId, + fulfiller: oneshot::Sender, Error>>, + ) -> QuestionRef { + QuestionRef { + connection_state: state, + id, + fulfiller: Some(fulfiller), + } } fn fulfill(&mut self, response: Promise, Error>) { if let Some(fulfiller) = self.fulfiller.take() { @@ -195,7 +229,7 @@ impl QuestionRef { } } -impl Drop for QuestionRef { +impl Drop for QuestionRef { fn drop(&mut self) { let mut questions = self.connection_state.questions.borrow_mut(); match questions.slots[self.id as usize] { @@ -232,7 +266,10 @@ impl Drop for QuestionRef { } } -struct Answer where VatId: 'static { +struct Answer +where + VatId: 'static, +{ // True from the point when the Call message is received to the point when both the `Finish` // message has been received and the `Return` has been sent. active: bool, @@ -254,7 +291,7 @@ struct Answer where VatId: 'static { result_exports: Vec, } -impl Answer { +impl Answer { fn new() -> Answer { Answer { active: false, @@ -287,7 +324,10 @@ impl Export { } } -pub struct Import where VatId: 'static { +pub struct Import +where + VatId: 'static, +{ // Becomes null when the import is destroyed. import_client: Option<(Weak>>, usize)>, @@ -300,7 +340,7 @@ pub struct Import where VatId: 'static { promise_client_to_resolve: Option>>>, } -impl Import { +impl Import { fn new() -> Import { Import { import_client: None, @@ -316,13 +356,15 @@ struct Embargo { impl Embargo { fn new(fulfiller: oneshot::Sender>) -> Embargo { - Embargo { fulfiller: Some(fulfiller) } + Embargo { + fulfiller: Some(fulfiller), + } } } -fn to_pipeline_ops(ops: ::capnp::struct_list::Reader) - -> ::capnp::Result> -{ +fn to_pipeline_ops( + ops: ::capnp::struct_list::Reader, +) -> ::capnp::Result> { let mut result = Vec::new(); for op in ops.iter() { match op.which()? { @@ -350,30 +392,36 @@ fn from_error(error: &Error, mut builder: exception::Builder) { fn remote_exception_to_error(exception: exception::Reader) -> Error { let (kind, reason) = match (exception.get_type(), exception.get_reason()) { - (Ok(exception::Type::Failed), Ok(reason)) => - (::capnp::ErrorKind::Failed, reason), - (Ok(exception::Type::Overloaded), Ok(reason)) => - (::capnp::ErrorKind::Overloaded, reason), - (Ok(exception::Type::Disconnected), Ok(reason)) => - (::capnp::ErrorKind::Disconnected, reason), - (Ok(exception::Type::Unimplemented), Ok(reason)) => - (::capnp::ErrorKind::Unimplemented, reason), + (Ok(exception::Type::Failed), Ok(reason)) => (::capnp::ErrorKind::Failed, reason), + (Ok(exception::Type::Overloaded), Ok(reason)) => (::capnp::ErrorKind::Overloaded, reason), + (Ok(exception::Type::Disconnected), Ok(reason)) => { + (::capnp::ErrorKind::Disconnected, reason) + } + (Ok(exception::Type::Unimplemented), Ok(reason)) => { + (::capnp::ErrorKind::Unimplemented, reason) + } _ => (::capnp::ErrorKind::Failed, "(malformed error)"), }; - Error { description: format!("remote exception: {}", reason), kind } + Error { + description: format!("remote exception: {}", reason), + kind, + } } -pub struct ConnectionErrorHandler where VatId: 'static { +pub struct ConnectionErrorHandler +where + VatId: 'static, +{ weak_state: Weak>, } -impl ConnectionErrorHandler { +impl ConnectionErrorHandler { fn new(weak_state: Weak>) -> ConnectionErrorHandler { ConnectionErrorHandler { weak_state } } } -impl crate::task_set::TaskReaper for ConnectionErrorHandler { +impl crate::task_set::TaskReaper for ConnectionErrorHandler { fn task_failed(&mut self, error: ::capnp::Error) { if let Some(state) = self.weak_state.upgrade() { state.disconnect(error) @@ -381,7 +429,10 @@ impl crate::task_set::TaskReaper for ConnectionErrorHandle } } -pub struct ConnectionState where VatId: 'static { +pub struct ConnectionState +where + VatId: 'static, +{ bootstrap_cap: Box, exports: RefCell>, questions: RefCell>>, @@ -399,13 +450,12 @@ pub struct ConnectionState where VatId: 'static { client_downcast_map: RefCell>>, } -impl ConnectionState { +impl ConnectionState { pub fn new( bootstrap_cap: Box, connection: Box>, - disconnect_fulfiller: oneshot::Sender>) - -> (TaskSet, Rc>) - { + disconnect_fulfiller: oneshot::Sender>, + ) -> (TaskSet, Rc>) { let state = Rc::new(ConnectionState { bootstrap_cap, exports: RefCell::new(ExportTable::new()), @@ -419,14 +469,18 @@ impl ConnectionState { disconnect_fulfiller: RefCell::new(Some(disconnect_fulfiller)), client_downcast_map: RefCell::new(HashMap::new()), }); - let (mut handle, tasks) = TaskSet::new(Box::new(ConnectionErrorHandler::new(Rc::downgrade(&state)))); + let (mut handle, tasks) = + TaskSet::new(Box::new(ConnectionErrorHandler::new(Rc::downgrade(&state)))); handle.add(ConnectionState::message_loop(Rc::downgrade(&state))); *state.tasks.borrow_mut() = Some(handle); (tasks, state) } - fn new_outgoing_message(&self, first_segment_words: u32) -> capnp::Result> { + fn new_outgoing_message( + &self, + first_segment_words: u32, + ) -> capnp::Result> { match self.connection.borrow_mut().as_mut() { Err(e) => Err(e.clone()), Ok(c) => Ok(c.new_outgoing_message(first_segment_words)), @@ -463,9 +517,13 @@ impl ConnectionState { } let len = self.exports.borrow().slots.len(); - for idx in 0..len { + for idx in 0..len { if let Some(exp) = self.exports.borrow_mut().slots[idx].take() { - let Export { client_hook, resolve_op, .. } = exp; + let Export { + client_hook, + resolve_op, + .. + } = exp; clients_to_release.push(client_hook); resolve_ops_to_release.push(resolve_op); } @@ -502,7 +560,11 @@ impl ConnectionState { Ok(ref mut c) => { let mut message = c.new_outgoing_message(100); // TODO estimate size { - let builder = message.get_body().unwrap().init_as::().init_abort(); + let builder = message + .get_body() + .unwrap() + .init_as::() + .init_abort(); from_error(&error, builder); } let _ = message.send(); @@ -525,7 +587,8 @@ impl ConnectionState { } } }); - let maybe_fulfiller = mem::replace(&mut *self.disconnect_fulfiller.borrow_mut(), None); + let maybe_fulfiller = + mem::replace(&mut *self.disconnect_fulfiller.borrow_mut(), None); match maybe_fulfiller { None => unreachable!(), Some(fulfiller) => { @@ -540,22 +603,27 @@ impl ConnectionState { // Transform a future into a promise that gets executed even if it is never polled. // Dropping the returned promise cancels the computation. fn eagerly_evaluate(&self, task: F) -> Promise - where F: Future> + 'static + Unpin, - T: 'static + where + F: Future> + 'static + Unpin, + T: 'static, { - let (tx, rx) = oneshot::channel::>(); + let (tx, rx) = oneshot::channel::>(); let (tx2, rx2) = oneshot::channel::<()>(); - let f1 = Box::pin(task.map(move |r| { let _ = tx.send(r);})) - as Pin + Unpin>>; - let f2 = Box::pin(rx2.map(drop)) - as Pin + Unpin>>; + let f1 = Box::pin(task.map(move |r| { + let _ = tx.send(r); + })) as Pin + Unpin>>; + let f2 = Box::pin(rx2.map(drop)) as Pin + Unpin>>; self.add_task(future::select(f1, f2).map(|_| Ok(()))); - Promise::from_future(rx.map_err(crate::canceled_to_error).map(|r| {drop(tx2); r?})) + Promise::from_future(rx.map_err(crate::canceled_to_error).map(|r| { + drop(tx2); + r? + })) } fn add_task(&self, task: F) - where F: Future> + 'static + where + F: Future> + 'static, { if let Some(ref mut tasks) = *self.tasks.borrow_mut() { tasks.add(task); @@ -567,8 +635,12 @@ impl ConnectionState { let (fulfiller, promise) = oneshot::channel(); let promise = promise.map_err(crate::canceled_to_error); - let promise = promise.and_then(|response_promise| response_promise ); - let question_ref = Rc::new(RefCell::new(QuestionRef::new(state.clone(), question_id, fulfiller))); + let promise = promise.and_then(|response_promise| response_promise); + let question_ref = Rc::new(RefCell::new(QuestionRef::new( + state.clone(), + question_id, + fulfiller, + ))); let promise = promise.attach(question_ref.clone()); match state.questions.borrow_mut().slots[question_id as usize] { Some(ref mut q) => { @@ -580,7 +652,11 @@ impl ConnectionState { Ok(ref mut c) => { let mut message = c.new_outgoing_message(100); // TODO estimate size { - let mut builder = message.get_body().unwrap().init_as::().init_bootstrap(); + let mut builder = message + .get_body() + .unwrap() + .init_as::() + .init_bootstrap(); builder.set_question_id(question_id); } let _ = message.send(); @@ -594,8 +670,11 @@ impl ConnectionState { fn message_loop(weak_state: Weak>) -> Promise<(), capnp::Error> { let state = match weak_state.upgrade() { - None => return Promise::err( - Error::disconnected("message loop cannot continue without a connection".into())), + None => { + return Promise::err(Error::disconnected( + "message loop cannot continue without a connection".into(), + )) + } Some(c) => c, }; @@ -608,11 +687,15 @@ impl ConnectionState { match promise.await? { Some(m) => { ConnectionState::handle_message(weak_state.clone(), m)?; - weak_state.upgrade().expect("message loop outlived connection state?") + weak_state + .upgrade() + .expect("message loop outlived connection state?") .add_task(ConnectionState::message_loop(weak_state)); } None => { - weak_state.upgrade().expect("message loop outlived connection state?") + weak_state + .upgrade() + .expect("message loop outlived connection state?") .disconnect(Error::disconnected("Peer disconnected.".to_string())); } } @@ -620,8 +703,10 @@ impl ConnectionState { }) } - fn send_unimplemented(connection_state: Rc>, - message: Box) -> capnp::Result<()> { + fn send_unimplemented( + connection_state: Rc>, + message: Box, + ) -> capnp::Result<()> { let mut out_message = connection_state.new_outgoing_message(50)?; // XXX size hint { let mut root: message::Builder = out_message.get_body()?.get_as()?; @@ -631,42 +716,45 @@ impl ConnectionState { Ok(()) } - fn handle_unimplemented(connection_state: Rc>, - message: message::Reader) -> capnp::Result<()> { + fn handle_unimplemented( + connection_state: Rc>, + message: message::Reader, + ) -> capnp::Result<()> { match message.which()? { message::Resolve(resolve) => { let resolve = resolve?; match resolve.which()? { - resolve::Cap(c) => { - match c?.which()? { - cap_descriptor::None(()) => (), - cap_descriptor::SenderHosted(export_id) => { - connection_state.release_export(export_id, 1)?; - } - cap_descriptor::SenderPromise(export_id) => { - connection_state.release_export(export_id, 1)?; - } - cap_descriptor::ReceiverAnswer(_) | - cap_descriptor::ReceiverHosted(_) => (), - cap_descriptor::ThirdPartyHosted(_) => { - return Err(Error::failed( - "Peer claims we resolved a ThirdPartyHosted cap.".to_string())); - }, + resolve::Cap(c) => match c?.which()? { + cap_descriptor::None(()) => (), + cap_descriptor::SenderHosted(export_id) => { + connection_state.release_export(export_id, 1)?; } - } + cap_descriptor::SenderPromise(export_id) => { + connection_state.release_export(export_id, 1)?; + } + cap_descriptor::ReceiverAnswer(_) | cap_descriptor::ReceiverHosted(_) => (), + cap_descriptor::ThirdPartyHosted(_) => { + return Err(Error::failed( + "Peer claims we resolved a ThirdPartyHosted cap.".to_string(), + )); + } + }, resolve::Exception(_) => (), } } _ => { return Err(Error::failed( - "Peer did not implement required RPC message type.".to_string())); + "Peer did not implement required RPC message type.".to_string(), + )); } } Ok(()) } - fn handle_bootstrap(connection_state: Rc>, - bootstrap: bootstrap::Reader) -> capnp::Result<()> { + fn handle_bootstrap( + connection_state: Rc>, + bootstrap: bootstrap::Reader, + ) -> capnp::Result<()> { use ::capnp::traits::ImbueMut; let answer_id = bootstrap.get_question_id(); @@ -678,7 +766,10 @@ impl ConnectionState { let mut response = connection_state.new_outgoing_message(50)?; // XXX size hint let result_exports = { - let mut ret = response.get_body()?.init_as::().init_return(); + let mut ret = response + .get_body()? + .init_as::() + .init_return(); ret.set_answer_id(answer_id); let cap = connection_state.bootstrap_cap.clone(); @@ -691,8 +782,7 @@ impl ConnectionState { } assert_eq!(cap_table.len(), 1); - ConnectionState::write_descriptors(&connection_state, &cap_table, - payload) + ConnectionState::write_descriptors(&connection_state, &cap_table, payload) }; let slots = &mut connection_state.answers.borrow_mut().slots; @@ -705,14 +795,17 @@ impl ConnectionState { answer.return_has_been_sent = true; answer.result_exports = result_exports; answer.pipeline = Some(Box::new(SingleCapPipeline::new( - connection_state.bootstrap_cap.clone()))); + connection_state.bootstrap_cap.clone(), + ))); let _ = response.send(); Ok(()) } - fn handle_finish(connection_state: Rc>, - finish: finish::Reader) -> capnp::Result<()> { + fn handle_finish( + connection_state: Rc>, + finish: finish::Reader, + ) -> capnp::Result<()> { let mut exports_to_release = Vec::new(); let answer_id = finish.get_question_id(); @@ -720,13 +813,17 @@ impl ConnectionState { let answers_slots = &mut connection_state.answers.borrow_mut().slots; match answers_slots.get_mut(&answer_id) { None => { - return Err(Error::failed( - format!("Invalid question ID {} in Finish message.", answer_id))); + return Err(Error::failed(format!( + "Invalid question ID {} in Finish message.", + answer_id + ))); } Some(ref mut answer) => { if !answer.active { - return Err(Error::failed( - format!("'Finish' for invalid question ID {}.", answer_id))); + return Err(Error::failed(format!( + "'Finish' for invalid question ID {}.", + answer_id + ))); } answer.received_finish.set(true); @@ -752,13 +849,14 @@ impl ConnectionState { Ok(()) } - fn handle_disembargo(connection_state: Rc>, - disembargo: disembargo::Reader) -> capnp::Result<()> { + fn handle_disembargo( + connection_state: Rc>, + disembargo: disembargo::Reader, + ) -> capnp::Result<()> { let context = disembargo.get_context(); match context.which()? { disembargo::context::SenderLoopback(embargo_id) => { - let mut target = - connection_state.get_message_target(disembargo.get_target()?)?; + let mut target = connection_state.get_message_target(disembargo.get_target()?)?; while let Some(resolved) = target.get_resolved() { target = resolved; } @@ -777,18 +875,23 @@ impl ConnectionState { { let root: message::Builder = message.get_body()?.init_as(); let mut disembargo = root.init_disembargo(); - disembargo.reborrow().init_context().set_receiver_loopback(embargo_id); - - let redirect = match Client::from_ptr(target.get_ptr(), - &connection_state_ref1) { - Some(c) => c.write_target(disembargo.init_target()), - None => unreachable!(), - }; + disembargo + .reborrow() + .init_context() + .set_receiver_loopback(embargo_id); + + let redirect = + match Client::from_ptr(target.get_ptr(), &connection_state_ref1) { + Some(c) => c.write_target(disembargo.init_target()), + None => unreachable!(), + }; if redirect.is_some() { return Err(Error::failed( "'Disembargo' of type 'senderLoopback' sent to an object that \ does not appear to have been the subject of a previous \ - 'Resolve' message.".to_string())); + 'Resolve' message." + .to_string(), + )); } } let _ = message.send(); @@ -804,27 +907,31 @@ impl ConnectionState { let fulfiller = embargo.fulfiller.take().unwrap(); let _ = fulfiller.send(Ok(())); } else { - return Err( - Error::failed( - "Invalid embargo ID in `Disembargo.context.receiverLoopback".to_string())); + return Err(Error::failed( + "Invalid embargo ID in `Disembargo.context.receiverLoopback".to_string(), + )); } connection_state.embargoes.borrow_mut().erase(embargo_id); } - disembargo::context::Accept(_) | - disembargo::context::Provide(_) => { - return Err( - Error::unimplemented( - "Disembargo::Context::Provide/Accept not implemented".to_string())); + disembargo::context::Accept(_) | disembargo::context::Provide(_) => { + return Err(Error::unimplemented( + "Disembargo::Context::Provide/Accept not implemented".to_string(), + )); } } Ok(()) } - fn handle_message(weak_state: Weak>, - message: Box) -> ::capnp::Result<()> { + fn handle_message( + weak_state: Weak>, + message: Box, + ) -> ::capnp::Result<()> { let connection_state = match weak_state.upgrade() { - None => return Err( - Error::disconnected("handle_message() cannot continue without a connection".into())), + None => { + return Err(Error::disconnected( + "handle_message() cannot continue without a connection".into(), + )) + } Some(c) => c, }; @@ -833,9 +940,7 @@ impl ConnectionState { Ok(message::Unimplemented(message)) => { Self::handle_unimplemented(connection_state, message?)? } - Ok(message::Abort(abort)) => { - return Err(remote_exception_to_error(abort?)) - } + Ok(message::Abort(abort)) => return Err(remote_exception_to_error(abort?)), Ok(message::Bootstrap(bootstrap)) => { Self::handle_bootstrap(connection_state, bootstrap?)? } @@ -846,20 +951,36 @@ impl ConnectionState { let redirect_results = match call.get_send_results_to().which()? { call::send_results_to::Caller(()) => false, call::send_results_to::Yourself(()) => true, - call::send_results_to::ThirdParty(_) => - return Err(Error::failed("Unsupported `Call.sendResultsTo`.".to_string())), + call::send_results_to::ThirdParty(_) => { + return Err(Error::failed( + "Unsupported `Call.sendResultsTo`.".to_string(), + )) + } }; let payload = call.get_params()?; - (call.get_interface_id(), call.get_method_id(), call.get_question_id(), - ConnectionState::receive_caps(connection_state.clone(), - payload.get_cap_table()?)?, - redirect_results) + ( + call.get_interface_id(), + call.get_method_id(), + call.get_question_id(), + ConnectionState::receive_caps( + connection_state.clone(), + payload.get_cap_table()?, + )?, + redirect_results, + ) }; - if connection_state.answers.borrow().slots.contains_key(&question_id) { - return Err(Error::failed( - format!("Received a new call on in-use question id {}", question_id))); + if connection_state + .answers + .borrow() + .slots + .contains_key(&question_id) + { + return Err(Error::failed(format!( + "Received a new call on in-use question id {}", + question_id + ))); } let params = Params::new(message, cap_table_array); @@ -868,13 +989,20 @@ impl ConnectionState { let (results_inner_fulfiller, results_inner_promise) = oneshot::channel(); let results_inner_promise = results_inner_promise.map_err(crate::canceled_to_error); - let results = Results::new(&connection_state, question_id, redirect_results, - results_inner_fulfiller, answer.received_finish.clone()); + let results = Results::new( + &connection_state, + question_id, + redirect_results, + results_inner_fulfiller, + answer.received_finish.clone(), + ); let (redirected_results_done_promise, redirected_results_done_fulfiller) = if redirect_results { let (f, p) = oneshot::channel::, Error>>(); - let p = p.map_err(crate::canceled_to_error).and_then(|x| future::ready(x)); + let p = p + .map_err(crate::canceled_to_error) + .and_then(|x| future::ready(x)); (Some(Promise::from_future(p)), Some(f)) } else { (None, None) @@ -889,27 +1017,30 @@ impl ConnectionState { answer.active = true; } - let call_promise = capability.call(interface_id, method_id, Box::new(params), Box::new(results)); + let call_promise = + capability.call(interface_id, method_id, Box::new(params), Box::new(results)); let (pipeline_sender, mut pipeline) = queued::Pipeline::new(); - let promise = call_promise.then(move |call_result| { - results_inner_promise.then(move |result| { - future::ready(ResultsDone::from_results_inner(result, call_result, pipeline_sender)) + let promise = call_promise + .then(move |call_result| { + results_inner_promise.then(move |result| { + future::ready(ResultsDone::from_results_inner( + result, + call_result, + pipeline_sender, + )) + }) }) - }).then(move |v| { - match redirected_results_done_fulfiller { - Some(f) => { - match v { - Ok(ref r) => - drop(f.send(Ok(Response::redirected(r.clone())))), - Err(ref e) => - drop(f.send(Err(e.clone()))), - } + .then(move |v| { + match redirected_results_done_fulfiller { + Some(f) => match v { + Ok(ref r) => drop(f.send(Ok(Response::redirected(r.clone())))), + Err(ref e) => drop(f.send(Err(e.clone()))), + }, + None => (), } - None => (), - } - Promise::ok(()) - }); + Promise::ok(()) + }); let fork = promise.shared(); pipeline.drive(fork.clone()); @@ -923,11 +1054,11 @@ impl ConnectionState { answer.redirected_results = redirected_results_done_promise; // More to do here? } else { - answer.call_completion_promise = Some( - connection_state.eagerly_evaluate(fork)); + answer.call_completion_promise = + Some(connection_state.eagerly_evaluate(fork)); } } - None => unreachable!() + None => unreachable!(), } } } @@ -940,54 +1071,59 @@ impl ConnectionState { Some(ref mut question) => { question.is_awaiting_return = false; match question.self_ref { - Some(ref question_ref) => { - match ret.which()? { - return_::Results(results) => { - let cap_table = - ConnectionState::receive_caps(connection_state.clone(), - results?.get_cap_table()?)?; - - let question_ref = question_ref.upgrade() - .expect("dangling question ref?"); - let response = Response::new(connection_state.clone(), - question_ref.clone(), - message, cap_table); - question_ref.borrow_mut().fulfill(Promise::ok(response)); - } - return_::Exception(e) => { - let tmp = question_ref.upgrade().expect("dangling question ref?"); - tmp.borrow_mut().reject(remote_exception_to_error(e?)); - } - return_::Canceled(_) => { - unimplemented!() - } - return_::ResultsSentElsewhere(_) => { - unimplemented!() - } - return_::TakeFromOtherQuestion(id) => { - if let Some(ref mut answer) = - connection_state.answers.borrow_mut().slots.get_mut(&id) - { - if let Some(res) = answer.redirected_results.take() { - let tmp = question_ref.upgrade() - .expect("dangling question ref?"); - tmp.borrow_mut().fulfill(res); - } else { - return Err(Error::failed(format!( - "return.takeFromOtherQuestion referenced a call that \ - did not use sendResultsTo.yourself."))); - } + Some(ref question_ref) => match ret.which()? { + return_::Results(results) => { + let cap_table = ConnectionState::receive_caps( + connection_state.clone(), + results?.get_cap_table()?, + )?; + + let question_ref = + question_ref.upgrade().expect("dangling question ref?"); + let response = Response::new( + connection_state.clone(), + question_ref.clone(), + message, + cap_table, + ); + question_ref.borrow_mut().fulfill(Promise::ok(response)); + } + return_::Exception(e) => { + let tmp = + question_ref.upgrade().expect("dangling question ref?"); + tmp.borrow_mut().reject(remote_exception_to_error(e?)); + } + return_::Canceled(_) => { + unimplemented!() + } + return_::ResultsSentElsewhere(_) => { + unimplemented!() + } + return_::TakeFromOtherQuestion(id) => { + if let Some(ref mut answer) = + connection_state.answers.borrow_mut().slots.get_mut(&id) + { + if let Some(res) = answer.redirected_results.take() { + let tmp = question_ref + .upgrade() + .expect("dangling question ref?"); + tmp.borrow_mut().fulfill(res); } else { return Err(Error::failed(format!( - "return.takeFromOtherQuestion had invalid answer ID."))); + "return.takeFromOtherQuestion referenced a call that \ + did not use sendResultsTo.yourself."))); } - } - return_::AcceptFromThirdParty(_) => { - drop(questions); - ConnectionState::send_unimplemented(connection_state, message)?; + } else { + return Err(Error::failed(format!( + "return.takeFromOtherQuestion had invalid answer ID." + ))); } } - } + return_::AcceptFromThirdParty(_) => { + drop(questions); + ConnectionState::send_unimplemented(connection_state, message)?; + } + }, None => { match ret.which()? { return_::TakeFromOtherQuestion(_) => { @@ -1004,14 +1140,14 @@ impl ConnectionState { } } None => { - return Err(Error::failed( - format!("Invalid question ID in Return message: {}", question_id))); + return Err(Error::failed(format!( + "Invalid question ID in Return message: {}", + question_id + ))); } } } - Ok(message::Finish(finish)) => { - Self::handle_finish(connection_state, finish?)? - } + Ok(message::Finish(finish)) => Self::handle_finish(connection_state, finish?)?, Ok(message::Resolve(resolve)) => { let resolve = resolve?; let replacement_or_error = match resolve.which()? { @@ -1019,8 +1155,9 @@ impl ConnectionState { match ConnectionState::receive_cap(connection_state.clone(), c?)? { Some(cap) => Ok(cap), None => { - return Err(Error::failed( - format!("'Resolve' contained 'CapDescriptor.none'."))); + return Err(Error::failed(format!( + "'Resolve' contained 'CapDescriptor.none'." + ))); } } } @@ -1048,8 +1185,9 @@ impl ConnectionState { } } None => { - return Err(Error::failed( - format!("Got 'Resolve' for a non-promise import."))); + return Err(Error::failed(format!( + "Got 'Resolve' for a non-promise import." + ))); } } } @@ -1061,9 +1199,12 @@ impl ConnectionState { Ok(message::Disembargo(disembargo)) => { Self::handle_disembargo(connection_state, disembargo?)? } - Ok(message::Provide(_)) | Ok(message::Accept(_)) | - Ok(message::Join(_)) | Ok(message::ObsoleteSave(_)) | Ok(message::ObsoleteDelete(_)) | - Err(::capnp::NotInSchema(_)) => { + Ok(message::Provide(_)) + | Ok(message::Accept(_)) + | Ok(message::Join(_)) + | Ok(message::ObsoleteSave(_)) + | Ok(message::ObsoleteDelete(_)) + | Err(::capnp::NotInSchema(_)) => { ConnectionState::send_unimplemented(connection_state, message)?; } } @@ -1095,7 +1236,9 @@ impl ConnectionState { match self.exports.borrow_mut().find(id) { Some(e) => { if refcount > e.refcount { - return Err(Error::failed("Tried to drop export's refcount below zero.".to_string())); + return Err(Error::failed( + "Tried to drop export's refcount below zero.".to_string(), + )); } else { e.refcount -= refcount; if e.refcount == 0 { @@ -1105,7 +1248,9 @@ impl ConnectionState { } } None => { - return Err(Error::failed("Tried to release invalid export ID.".to_string())); + return Err(Error::failed( + "Tried to release invalid export ID.".to_string(), + )); } } if erase_export { @@ -1123,21 +1268,20 @@ impl ConnectionState { } fn get_brand(&self) -> usize { - self as * const _ as usize + self as *const _ as usize } - fn get_message_target(&self, target: message_target::Reader) - -> ::capnp::Result> - { + fn get_message_target( + &self, + target: message_target::Reader, + ) -> ::capnp::Result> { match target.which()? { message_target::ImportedCap(export_id) => { match self.exports.borrow().slots.get(export_id as usize) { - Some(&Some(ref exp)) => { - Ok(exp.client_hook.clone()) - } - _ => { - Err(Error::failed("Message target is not a current export ID.".to_string())) - } + Some(&Some(ref exp)) => Ok(exp.client_hook.clone()), + _ => Err(Error::failed( + "Message target is not a current export ID.".to_string(), + )), } } message_target::PromisedAnswer(promised_answer) => { @@ -1145,15 +1289,17 @@ impl ConnectionState { let question_id = promised_answer.get_question_id(); match self.answers.borrow().slots.get(&question_id) { - None => { - Err(Error::failed("PromisedAnswer.questionId is not a current question.".to_string())) - } + None => Err(Error::failed( + "PromisedAnswer.questionId is not a current question.".to_string(), + )), Some(base) => { let pipeline = match base.pipeline { Some(ref pipeline) => pipeline.add_ref(), None => Box::new(broken::Pipeline::new(Error::failed( "Pipeline call on a request that returned not capabilities or was \ - already closed.".to_string()))) as Box, + already closed." + .to_string(), + ))) as Box, }; let ops = to_pipeline_ops(promised_answer.get_transform()?)?; Ok(pipeline.get_pipelined_cap(&ops)) @@ -1172,9 +1318,11 @@ impl ConnectionState { /// resolved, and so the request may have been built on the assumption that it would be sent over /// this network connection, but then the promise resolved to point somewhere else before the /// request was sent. Now the request has to be redirected to the new target instead. - fn write_target(&self, cap: &dyn ClientHook, target: message_target::Builder) - -> Option> - { + fn write_target( + &self, + cap: &dyn ClientHook, + target: message_target::Builder, + ) -> Option> { if cap.get_brand() == self.get_brand() { match Client::from_ptr(cap.get_ptr(), self) { Some(c) => c.write_target(target), @@ -1192,9 +1340,7 @@ impl ConnectionState { } if client.get_brand() == self.get_brand() { match self.client_downcast_map.borrow().get(&client.get_ptr()) { - Some(c) => { - Box::new(c.upgrade().expect("dangling client?")) - } + Some(c) => Box::new(c.upgrade().expect("dangling client?")), None => unreachable!(), } } else { @@ -1205,13 +1351,16 @@ impl ConnectionState { /// Implements exporting of a promise. The promise has been exported under the given ID, and is /// to eventually resolve to the ClientHook produced by `promise`. This method waits for that /// resolve to happen and then sends the appropriate `Resolve` message to the peer. - fn resolve_exported_promise(state: &Rc>, export_id: ExportId, - promise: Promise, Error>) - -> Promise<(), Error> - { + fn resolve_exported_promise( + state: &Rc>, + export_id: ExportId, + promise: Promise, Error>, + ) -> Promise<(), Error> { let weak_connection_state = Rc::downgrade(state); state.eagerly_evaluate(promise.map(move |resolution_result| { - let connection_state = weak_connection_state.upgrade().expect("dangling connection state?"); + let connection_state = weak_connection_state + .upgrade() + .expect("dangling connection state?"); match resolution_result { Ok(resolution) => { @@ -1222,8 +1371,12 @@ impl ConnectionState { // Update the export table to point at this object instead. We know that our // entry in the export table is still live because when it is destroyed the // asynchronous resolution task (i.e. this code) is canceled. - if let Some(ref mut exp) = connection_state.exports.borrow_mut().find(export_id) { - connection_state.exports_by_cap.borrow_mut().remove(&exp.client_hook.get_ptr()); + if let Some(ref mut exp) = connection_state.exports.borrow_mut().find(export_id) + { + connection_state + .exports_by_cap + .borrow_mut() + .remove(&exp.client_hook.get_ptr()); exp.client_hook = resolution.clone(); } else { return Err(Error::failed("export table entry not found".to_string())); @@ -1249,8 +1402,11 @@ impl ConnectionState { let root: message::Builder = message.get_body()?.get_as()?; let mut resolve = root.init_resolve(); resolve.set_promise_id(export_id); - let _export = ConnectionState::write_descriptor(&connection_state, &resolution, - resolve.init_cap())?; + let _export = ConnectionState::write_descriptor( + &connection_state, + &resolution, + resolve.init_cap(), + )?; } let _ = message.send(); Ok(()) @@ -1271,10 +1427,11 @@ impl ConnectionState { })) } - fn write_descriptor(state: &Rc>, - cap: &Box, - mut descriptor: cap_descriptor::Builder) -> ::capnp::Result> { - + fn write_descriptor( + state: &Rc>, + cap: &Box, + mut descriptor: cap_descriptor::Builder, + ) -> ::capnp::Result> { // Find the innermost wrapped capability. let mut inner = cap.clone(); while let Some(resolved) = inner.get_resolved() { @@ -1310,8 +1467,9 @@ impl ConnectionState { Some(wrapped) => { // This is a promise. Arrange for the `Resolve` message to be sent later. if let Some(ref mut exp) = state.exports.borrow_mut().find(export_id) { - exp.resolve_op = - ConnectionState::resolve_exported_promise(state, export_id, wrapped); + exp.resolve_op = ConnectionState::resolve_exported_promise( + state, export_id, wrapped, + ); } descriptor.set_sender_promise(export_id); } @@ -1324,18 +1482,23 @@ impl ConnectionState { } } - fn write_descriptors(state: &Rc>, - cap_table: &[Option>], - payload: payload::Builder) - -> Vec - { + fn write_descriptors( + state: &Rc>, + cap_table: &[Option>], + payload: payload::Builder, + ) -> Vec { let mut cap_table_builder = payload.init_cap_table(cap_table.len() as u32); let mut exports = Vec::new(); - for idx in 0 .. cap_table.len() { + for idx in 0..cap_table.len() { match cap_table[idx] { Some(ref cap) => { - match ConnectionState::write_descriptor(state, cap, - cap_table_builder.reborrow().get(idx as u32)).unwrap() { + match ConnectionState::write_descriptor( + state, + cap, + cap_table_builder.reborrow().get(idx as u32), + ) + .unwrap() + { Some(export_id) => { exports.push(export_id); } @@ -1350,19 +1513,30 @@ impl ConnectionState { exports } - fn import(state: Rc>, - import_id: ImportId, is_promise: bool) -> Box { + fn import( + state: Rc>, + import_id: ImportId, + is_promise: bool, + ) -> Box { let connection_state = state.clone(); let import_client = { let slots = &mut state.imports.borrow_mut().slots; let v = slots.entry(import_id).or_insert_with(Import::new); if v.import_client.is_some() { - v.import_client.as_ref().unwrap().0.upgrade().expect("dangling ref to import client?").clone() + v.import_client + .as_ref() + .unwrap() + .0 + .upgrade() + .expect("dangling ref to import client?") + .clone() } else { let import_client = ImportClient::new(&connection_state, import_id); - v.import_client = Some((Rc::downgrade(&import_client), - (&*import_client.borrow())as *const _ as usize )); + v.import_client = Some(( + Rc::downgrade(&import_client), + (&*import_client.borrow()) as *const _ as usize, + )); import_client } }; @@ -1387,10 +1561,10 @@ impl ConnectionState { // XXX do I need something like this? // Make sure the import is not destroyed while this promise exists. -// let promise = promise.attach(client.add_ref()); + // let promise = promise.attach(client.add_ref()); - let client = PromiseClient::new(&connection_state, client, - Some(import_id)); + let client = + PromiseClient::new(&connection_state, client, Some(import_id)); import.promise_client_to_resolve = Some(Rc::downgrade(&client)); let client: Box> = Box::new(client.into()); @@ -1399,7 +1573,9 @@ impl ConnectionState { } } } - None => { unreachable!() } + None => { + unreachable!() + } } } else { let client: Box> = Box::new(import_client.into()); @@ -1407,20 +1583,21 @@ impl ConnectionState { Some(ref mut v) => { v.app_client = Some(client.downgrade()); } - None => { unreachable!() } + None => { + unreachable!() + } }; client } } - fn receive_cap(state: Rc>, descriptor: cap_descriptor::Reader) - -> ::capnp::Result>> - { + fn receive_cap( + state: Rc>, + descriptor: cap_descriptor::Reader, + ) -> ::capnp::Result>> { match descriptor.which()? { - cap_descriptor::None(()) => { - Ok(None) - } + cap_descriptor::None(()) => Ok(None), cap_descriptor::SenderHosted(sender_hosted) => { Ok(Some(ConnectionState::import(state, sender_hosted, false))) } @@ -1431,7 +1608,9 @@ impl ConnectionState { if let Some(ref mut exp) = state.exports.borrow_mut().find(receiver_hosted) { Ok(Some(exp.client_hook.add_ref())) } else { - Ok(Some(broken::new_cap(Error::failed("invalid 'receivedHosted' export ID".to_string())))) + Ok(Some(broken::new_cap(Error::failed( + "invalid 'receivedHosted' export ID".to_string(), + )))) } } cap_descriptor::ReceiverAnswer(receiver_answer) => { @@ -1451,48 +1630,53 @@ impl ConnectionState { } None => (), } - Ok(Some(broken::new_cap(Error::failed("invalid 'receiver answer'".to_string())))) - } - cap_descriptor::ThirdPartyHosted(_third_party_hosted) => { - Err(Error::unimplemented("ThirdPartyHosted caps are not supported.".to_string())) + Ok(Some(broken::new_cap(Error::failed( + "invalid 'receiver answer'".to_string(), + )))) } + cap_descriptor::ThirdPartyHosted(_third_party_hosted) => Err(Error::unimplemented( + "ThirdPartyHosted caps are not supported.".to_string(), + )), } } - fn receive_caps(state: Rc>, - cap_table: ::capnp::struct_list::Reader) - -> ::capnp::Result>>> - { + fn receive_caps( + state: Rc>, + cap_table: ::capnp::struct_list::Reader, + ) -> ::capnp::Result>>> { let mut result = Vec::new(); for idx in 0..cap_table.len() { - result.push(ConnectionState::receive_cap(state.clone(), cap_table.get(idx))?); + result.push(ConnectionState::receive_cap( + state.clone(), + cap_table.get(idx), + )?); } Ok(result) } } -enum DisconnectorState -{ +enum DisconnectorState { Connected, Disconnecting, - Disconnected + Disconnected, } /// A `Future` that can be run to disconnect an `RpcSystem`'s ConnectionState and wait for it to be closed. -pub struct Disconnector where VatId: 'static { +pub struct Disconnector +where + VatId: 'static, +{ connection_state: Rc>>>>, - state: DisconnectorState, + state: DisconnectorState, } -impl Disconnector { - pub fn new(connection_state: Rc>>>>) -> Disconnector { +impl Disconnector { + pub fn new( + connection_state: Rc>>>>, + ) -> Disconnector { let state = match *(connection_state.borrow()) { - Some(_) => { - DisconnectorState::Connected - }, - None => { - DisconnectorState::Disconnected - } + Some(_) => DisconnectorState::Connected, + None => DisconnectorState::Disconnected, }; Disconnector { connection_state, @@ -1501,12 +1685,14 @@ impl Disconnector { } fn disconnect(&self) { if let Some(ref state) = *(self.connection_state.borrow()) { - state.disconnect(::capnp::Error::disconnected("client requested disconnect".to_owned())); + state.disconnect(::capnp::Error::disconnected( + "client requested disconnect".to_owned(), + )); } } } -impl Future for Disconnector +impl Future for Disconnector where VatId: 'static, { @@ -1517,50 +1703,59 @@ where DisconnectorState::Connected => { self.disconnect(); DisconnectorState::Disconnecting - }, + } DisconnectorState::Disconnecting => { if let Some(_) = *(self.connection_state.borrow()) { DisconnectorState::Disconnecting } else { DisconnectorState::Disconnected } - }, - DisconnectorState::Disconnected => { - DisconnectorState::Disconnected } + DisconnectorState::Disconnected => DisconnectorState::Disconnected, }; match self.state { DisconnectorState::Connected => unreachable!(), DisconnectorState::Disconnecting => { cx.waker().clone().wake(); Poll::Pending - }, + } DisconnectorState::Disconnected => Poll::Ready(Ok(())), } } } -struct ResponseState where VatId: 'static { +struct ResponseState +where + VatId: 'static, +{ _connection_state: Rc>, message: Box, cap_table: Vec>>, _question_ref: Rc>>, } -enum ResponseVariant where VatId: 'static { +enum ResponseVariant +where + VatId: 'static, +{ Rpc(ResponseState), LocallyRedirected(Box), } -struct Response where VatId: 'static { +struct Response +where + VatId: 'static, +{ variant: Rc>, } -impl Response { - fn new(connection_state: Rc>, - question_ref: Rc>>, - message: Box, - cap_table_array: Vec>>) -> Response { +impl Response { + fn new( + connection_state: Rc>, + question_ref: Rc>>, + message: Box, + cap_table_array: Vec>>, + ) -> Response { Response { variant: Rc::new(ResponseVariant::Rpc(ResponseState { _connection_state: connection_state, @@ -1570,72 +1765,76 @@ impl Response { })), } } - fn redirected(results_done: Box) - -> Response - { + fn redirected(results_done: Box) -> Response { Response { - variant: Rc::new(ResponseVariant::LocallyRedirected(results_done)) + variant: Rc::new(ResponseVariant::LocallyRedirected(results_done)), } } } -impl Clone for Response { +impl Clone for Response { fn clone(&self) -> Response { - Response { variant: self.variant.clone() } + Response { + variant: self.variant.clone(), + } } } -impl ResponseHook for Response { +impl ResponseHook for Response { fn get(&self) -> ::capnp::Result { match *self.variant { ResponseVariant::Rpc(ref state) => { - match state.message.get_body()?.get_as::()?.which()? { - message::Return(Ok(ret)) => { - match ret.which()? { - return_::Results(Ok(mut payload)) => { - use ::capnp::traits::Imbue; - payload.imbue(&state.cap_table); - Ok(payload.get_content()) - } - _ => unreachable!(), + match state + .message + .get_body()? + .get_as::()? + .which()? + { + message::Return(Ok(ret)) => match ret.which()? { + return_::Results(Ok(mut payload)) => { + use ::capnp::traits::Imbue; + payload.imbue(&state.cap_table); + Ok(payload.get_content()) } - } + _ => unreachable!(), + }, _ => unreachable!(), } } - ResponseVariant::LocallyRedirected(ref results_done) => { - results_done.get() - } + ResponseVariant::LocallyRedirected(ref results_done) => results_done.get(), } } } -struct Request where VatId: 'static { +struct Request +where + VatId: 'static, +{ connection_state: Rc>, target: Client, message: Box, cap_table: Vec>>, } -fn get_call(message: &mut Box) - -> ::capnp::Result -{ +fn get_call(message: &mut Box) -> ::capnp::Result { let message_root: message::Builder = message.get_body()?.get_as()?; match message_root.which()? { - message::Call(call) => { - call - } + message::Call(call) => call, _ => { unimplemented!() } } } -impl Request where VatId: 'static { - fn new(connection_state: Rc>, - _size_hint: Option<::capnp::MessageSize>, - target: Client) -> ::capnp::Result> { - +impl Request +where + VatId: 'static, +{ + fn new( + connection_state: Rc>, + _size_hint: Option<::capnp::MessageSize>, + target: Client, + ) -> ::capnp::Result> { let message = connection_state.new_outgoing_message(100)?; Ok(Request { connection_state, @@ -1650,15 +1849,21 @@ impl Request where VatId: 'static { message_root.init_call() } - fn send_internal(connection_state: Rc>, - mut message: Box, - cap_table: Vec>>, - is_tail_call: bool) - -> (Rc>>, Promise, Error>) - { + fn send_internal( + connection_state: Rc>, + mut message: Box, + cap_table: Vec>>, + is_tail_call: bool, + ) -> ( + Rc>>, + Promise, Error>, + ) { // Build the cap table. - let exports = ConnectionState::write_descriptors(&connection_state, &cap_table, - get_call(&mut message).unwrap().get_params().unwrap()); + let exports = ConnectionState::write_descriptors( + &connection_state, + &cap_table, + get_call(&mut message).unwrap().get_params().unwrap(), + ); // Init the question table. Do this after writing descriptors to avoid interference. let mut question = Question::::new(); @@ -1679,8 +1884,11 @@ impl Request where VatId: 'static { // Make the result promise. let (fulfiller, promise) = oneshot::channel::, Error>>(); let promise = promise.map_err(crate::canceled_to_error).and_then(|x| x); - let question_ref = Rc::new(RefCell::new( - QuestionRef::new(connection_state.clone(), question_id, fulfiller))); + let question_ref = Rc::new(RefCell::new(QuestionRef::new( + connection_state.clone(), + question_id, + fulfiller, + ))); match connection_state.questions.borrow_mut().slots[question_id as usize] { Some(ref mut q) => { @@ -1696,10 +1904,14 @@ impl Request where VatId: 'static { } } -impl RequestHook for Request { +impl RequestHook for Request { fn get(&mut self) -> any_pointer::Builder { use ::capnp::traits::ImbueMut; - let mut builder = get_call(&mut self.message).unwrap().get_params().unwrap().get_content(); + let mut builder = get_call(&mut self.message) + .unwrap() + .get_params() + .unwrap() + .get_content(); builder.imbue_mut(&mut self.cap_table); builder } @@ -1708,7 +1920,12 @@ impl RequestHook for Request { } fn send(self: Box) -> ::capnp::capability::RemotePromise { let tmp = *self; - let Request { connection_state, target, mut message, cap_table } = tmp; + let Request { + connection_state, + target, + mut message, + cap_table, + } = tmp; let write_target_result = { let call_builder: call::Builder = get_call(&mut message).unwrap(); target.write_target(call_builder.get_target().unwrap()) @@ -1718,10 +1935,21 @@ impl RequestHook for Request { // Whoops, this capability has been redirected while we were building the request! // We'll have to make a new request and do a copy. Ick. let mut call_builder: call::Builder = get_call(&mut message).unwrap(); - let mut replacement = redirect.new_call(call_builder.reborrow().get_interface_id(), - call_builder.reborrow().get_method_id(), None); - - replacement.set(call_builder.get_params().unwrap().get_content().into_reader()).unwrap(); + let mut replacement = redirect.new_call( + call_builder.reborrow().get_interface_id(), + call_builder.reborrow().get_method_id(), + None, + ); + + replacement + .set( + call_builder + .get_params() + .unwrap() + .get_content() + .into_reader(), + ) + .unwrap(); replacement.send() } None => { @@ -1731,29 +1959,36 @@ impl RequestHook for Request { let forked_promise2 = forked_promise1.clone(); // The pipeline must get notified of resolution before the app does to maintain ordering. - let pipeline = Pipeline::new(connection_state, question_ref.clone(), - Some(Promise::from_future(forked_promise1))); + let pipeline = Pipeline::new( + connection_state, + question_ref.clone(), + Some(Promise::from_future(forked_promise1)), + ); let resolved = pipeline.when_resolved(); let forked_promise2 = resolved.map(|_| Ok(())).and_then(|()| forked_promise2); - let app_promise = Promise::from_future(forked_promise2.map_ok(|response| { - ::capnp::capability::Response::new(Box::new(response)) - })); + let app_promise = Promise::from_future( + forked_promise2 + .map_ok(|response| ::capnp::capability::Response::new(Box::new(response))), + ); ::capnp::capability::RemotePromise { promise: app_promise, - pipeline: any_pointer::Pipeline::new(Box::new(pipeline)) + pipeline: any_pointer::Pipeline::new(Box::new(pipeline)), } } } } - fn tail_send(self: Box) - -> Option<(u32, Promise<(), Error>, Box)> - { + fn tail_send(self: Box) -> Option<(u32, Promise<(), Error>, Box)> { let tmp = *self; - let Request { connection_state, target, mut message, cap_table } = tmp; + let Request { + connection_state, + target, + mut message, + cap_table, + } = tmp; if connection_state.connection.borrow().is_err() { // Disconnected; fall back to a regular send() which will fail appropriately. @@ -1769,9 +2004,7 @@ impl RequestHook for Request { Some(_redirect) => { return None; } - None => { - Request::send_internal(connection_state.clone(), message, cap_table, true) - } + None => Request::send_internal(connection_state.clone(), message, cap_table, true), }; let promise = promise.map_ok(|_response| { @@ -1783,31 +2016,52 @@ impl RequestHook for Request { let question_id = question_ref.borrow().id; let pipeline = Pipeline::never_done(connection_state, question_ref); - Some((question_id, Promise::from_future(promise), Box::new(pipeline))) + Some(( + question_id, + Promise::from_future(promise), + Box::new(pipeline), + )) } } -enum PipelineVariant where VatId: 'static { +enum PipelineVariant +where + VatId: 'static, +{ Waiting(Rc>>), Resolved(Response), Broken(Error), } -struct PipelineState where VatId: 'static { +struct PipelineState +where + VatId: 'static, +{ variant: PipelineVariant, - redirect_later: Option, ::capnp::Error>>>>, + redirect_later: + Option, ::capnp::Error>>>>, connection_state: Rc>, #[allow(dead_code)] resolve_self_promise: Promise<(), Error>, - promise_clients_to_resolve: - RefCell>>, Vec), ()>>, + promise_clients_to_resolve: RefCell< + crate::sender_queue::SenderQueue< + (Weak>>, Vec), + (), + >, + >, resolution_waiters: crate::sender_queue::SenderQueue<(), ()>, } -impl PipelineState where VatId: 'static { - fn resolve(state: &Rc>>, response: Result, Error>) { +impl PipelineState +where + VatId: 'static, +{ + fn resolve( + state: &Rc>>, + response: Result, Error>, + ) { let to_resolve = { let tmp = state.borrow(); let r = tmp.promise_clients_to_resolve.borrow_mut().drain(); @@ -1815,14 +2069,10 @@ impl PipelineState where VatId: 'static { }; for ((c, ops), _) in to_resolve { let resolved = match response.clone() { - Ok(v) => { - match v.get() { - Ok(x) => { - x.get_pipelined_cap(&ops) - } - Err(e) => Err(e), - } - } + Ok(v) => match v.get() { + Ok(x) => x.get_pipelined_cap(&ops), + Err(e) => Err(e), + }, Err(e) => Err(e), }; if let Some(c) = c.upgrade() { @@ -1831,7 +2081,7 @@ impl PipelineState where VatId: 'static { } let new_variant = match response { - Ok(r) => PipelineVariant::Resolved(r), + Ok(r) => PipelineVariant::Resolved(r), Err(e) => PipelineVariant::Broken(e), }; let _old_variant = mem::replace(&mut state.borrow_mut().variant, new_variant); @@ -1843,16 +2093,19 @@ impl PipelineState where VatId: 'static { } } -struct Pipeline where VatId: 'static { +struct Pipeline +where + VatId: 'static, +{ state: Rc>>, } -impl Pipeline { - fn new(connection_state: Rc>, - question_ref: Rc>>, - redirect_later: Option, ::capnp::Error>>) - -> Pipeline - { +impl Pipeline { + fn new( + connection_state: Rc>, + question_ref: Rc>>, + redirect_later: Option, ::capnp::Error>>, + ) -> Pipeline { let state = Rc::new(RefCell::new(PipelineState { variant: PipelineVariant::Waiting(question_ref), connection_state: connection_state.clone(), @@ -1865,14 +2118,19 @@ impl Pipeline { Some(redirect_later_promise) => { let fork = redirect_later_promise.shared(); let this = Rc::downgrade(&state); - let resolve_self_promise = connection_state.eagerly_evaluate(fork.clone().then(move |response| { - let state = match this.upgrade() { - Some(s) => s, - None => return Promise::err(Error::failed("dangling reference to this".into())), - }; - PipelineState::resolve(&state, response); - Promise::ok(()) - })); + let resolve_self_promise = + connection_state.eagerly_evaluate(fork.clone().then(move |response| { + let state = match this.upgrade() { + Some(s) => s, + None => { + return Promise::err(Error::failed( + "dangling reference to this".into(), + )) + } + }; + PipelineState::resolve(&state, response); + Promise::ok(()) + })); state.borrow_mut().resolve_self_promise = resolve_self_promise; state.borrow_mut().redirect_later = Some(RefCell::new(fork.clone())); @@ -1886,10 +2144,10 @@ impl Pipeline { self.state.borrow_mut().resolution_waiters.push(()) } - fn never_done(connection_state: Rc>, - question_ref: Rc>>) - -> Pipeline - { + fn never_done( + connection_state: Rc>, + question_ref: Rc>>, + ) -> Pipeline { let state = Rc::new(RefCell::new(PipelineState { variant: PipelineVariant::Waiting(question_ref), connection_state, @@ -1903,17 +2161,24 @@ impl Pipeline { } } -impl PipelineHook for Pipeline { +impl PipelineHook for Pipeline { fn add_ref(&self) -> Box { - Box::new(Pipeline { state: self.state.clone() }) + Box::new(Pipeline { + state: self.state.clone(), + }) } fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box { self.get_pipelined_cap_move(ops.into()) } fn get_pipelined_cap_move(&self, ops: Vec) -> Box { match *self.state.borrow() { - PipelineState {variant: PipelineVariant::Waiting(ref question_ref), - ref connection_state, ref redirect_later, ref promise_clients_to_resolve, ..} => { + PipelineState { + variant: PipelineVariant::Waiting(ref question_ref), + ref connection_state, + ref redirect_later, + ref promise_clients_to_resolve, + .. + } => { // Wrap a PipelineClient in a PromiseClient. let pipeline_client = PipelineClient::new(connection_state, question_ref.clone(), ops.clone()); @@ -1921,11 +2186,11 @@ impl PipelineHook for Pipeline { match *redirect_later { Some(ref _r) => { let client: Client = pipeline_client.into(); - let promise_client = PromiseClient::new( - connection_state, - Box::new(client), - None); - promise_clients_to_resolve.borrow_mut().push_detach((Rc::downgrade(&promise_client), ops)); + let promise_client = + PromiseClient::new(connection_state, Box::new(client), None); + promise_clients_to_resolve + .borrow_mut() + .push_detach((Rc::downgrade(&promise_client), ops)); let result: Client = promise_client.into(); Box::new(result) } @@ -1936,12 +2201,14 @@ impl PipelineHook for Pipeline { } } } - PipelineState {variant: PipelineVariant::Resolved(ref response), ..} => { - response.get().unwrap().get_pipelined_cap(&ops[..]).unwrap() - } - PipelineState {variant: PipelineVariant::Broken(ref e), ..} => { - broken::new_cap(e.clone()) - } + PipelineState { + variant: PipelineVariant::Resolved(ref response), + .. + } => response.get().unwrap().get_pipelined_cap(&ops[..]).unwrap(), + PipelineState { + variant: PipelineVariant::Broken(ref e), + .. + } => broken::new_cap(e.clone()), } } } @@ -1952,14 +2219,11 @@ pub struct Params { } impl Params { - fn new(request: Box, - cap_table: Vec>>) - -> Params - { - Params { - request, - cap_table, - } + fn new( + request: Box, + cap_table: Vec>>, + ) -> Params { + Params { request, cap_table } } } @@ -1973,7 +2237,7 @@ impl ParamsHook for Params { content.imbue(&self.cap_table); Ok(content) } - _ => { + _ => { unreachable!() } } @@ -1981,11 +2245,20 @@ impl ParamsHook for Params { } enum ResultsVariant { - Rpc(Box, Vec>>), - LocallyRedirected(::capnp::message::Builder<::capnp::message::HeapAllocator>, Vec>>), + Rpc( + Box, + Vec>>, + ), + LocallyRedirected( + ::capnp::message::Builder<::capnp::message::HeapAllocator>, + Vec>>, + ), } -struct ResultsInner where VatId: 'static { +struct ResultsInner +where + VatId: 'static, +{ connection_state: Rc>, variant: Option, redirect_results: bool, @@ -1993,11 +2266,17 @@ struct ResultsInner where VatId: 'static { finish_received: Rc>, } -impl ResultsInner where VatId: 'static { +impl ResultsInner +where + VatId: 'static, +{ fn ensure_initialized(&mut self) { let answer_id = self.answer_id; if self.variant.is_none() { - match (self.redirect_results, self.connection_state.connection.borrow_mut().as_mut()) { + match ( + self.redirect_results, + self.connection_state.connection.borrow_mut().as_mut(), + ) { (false, Ok(c)) => { let mut message = c.new_outgoing_message(100); // size hint? @@ -2010,10 +2289,10 @@ impl ResultsInner where VatId: 'static { self.variant = Some(ResultsVariant::Rpc(message, Vec::new())); } _ => { - self.variant = - Some(ResultsVariant::LocallyRedirected( - ::capnp::message::Builder::new_default(), - Vec::new())); + self.variant = Some(ResultsVariant::LocallyRedirected( + ::capnp::message::Builder::new_default(), + Vec::new(), + )); } } } @@ -2021,21 +2300,25 @@ impl ResultsInner where VatId: 'static { } // This takes the place of both RpcCallContext and RpcServerResponse in capnproto-c++. -pub struct Results where VatId: 'static { +pub struct Results +where + VatId: 'static, +{ inner: Option>, results_done_fulfiller: Option>>, } - -impl Results where VatId: 'static { - fn new(connection_state: &Rc>, - answer_id: AnswerId, - redirect_results: bool, - fulfiller: oneshot::Sender>, - finish_received: Rc>, - ) - -> Results - { +impl Results +where + VatId: 'static, +{ + fn new( + connection_state: &Rc>, + answer_id: AnswerId, + redirect_results: bool, + fulfiller: oneshot::Sender>, + finish_received: Rc>, + ) -> Results { Results { inner: Some(ResultsInner { variant: None, @@ -2049,7 +2332,7 @@ impl Results where VatId: 'static { } } -impl Drop for Results { +impl Drop for Results { fn drop(&mut self) { match (self.inner.take(), self.results_done_fulfiller.take()) { (Some(inner), Some(fulfiller)) => { @@ -2061,7 +2344,7 @@ impl Drop for Results { } } -impl ResultsHook for Results { +impl ResultsHook for Results { fn get(&mut self) -> ::capnp::Result { use ::capnp::traits::ImbueMut; if let Some(ref mut inner) = self.inner { @@ -2071,19 +2354,17 @@ impl ResultsHook for Results { Some(ResultsVariant::Rpc(ref mut message, ref mut cap_table)) => { let root: message::Builder = message.get_body()?.get_as()?; match root.which()? { - message::Return(ret) => { - match ret?.which()? { - return_::Results(payload) => { - let mut content = payload?.get_content(); - content.imbue_mut(cap_table); - Ok(content) - } - _ => { - unreachable!() - } + message::Return(ret) => match ret?.which()? { + return_::Results(payload) => { + let mut content = payload?.get_content(); + content.imbue_mut(cap_table); + Ok(content) } - } - _ => { + _ => { + unreachable!() + } + }, + _ => { unreachable!() } } @@ -2103,16 +2384,18 @@ impl ResultsHook for Results { unimplemented!() } - fn direct_tail_call(mut self: Box, request: Box) - -> (Promise<(), Error>, Box) - { - if let (Some(inner), Some(fulfiller)) = (self.inner.take(), self.results_done_fulfiller.take()) { + fn direct_tail_call( + mut self: Box, + request: Box, + ) -> (Promise<(), Error>, Box) { + if let (Some(inner), Some(fulfiller)) = + (self.inner.take(), self.results_done_fulfiller.take()) + { let state = inner.connection_state.clone(); if request.get_brand() == state.get_brand() && !inner.redirect_results { // The tail call is headed towards the peer that called us in the first place, so we can // optimize out the return trip. if let Some((question_id, promise, pipeline)) = request.tail_send() { - let mut message = state.new_outgoing_message(100).expect("no connection?"); // size hint? { @@ -2133,7 +2416,6 @@ impl ResultsHook for Results { } else { unimplemented!() } - } else { unreachable!(); } @@ -2145,20 +2427,28 @@ impl ResultsHook for Results { } enum ResultsDoneVariant { - Rpc(Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, Vec>>), - LocallyRedirected(::capnp::message::Builder<::capnp::message::HeapAllocator>, Vec>>), + Rpc( + Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, + Vec>>, + ), + LocallyRedirected( + ::capnp::message::Builder<::capnp::message::HeapAllocator>, + Vec>>, + ), } struct ResultsDone { - inner: Rc + inner: Rc, } impl ResultsDone { - fn from_results_inner(results_inner: Result, Error>, - call_status: Result<(), Error>, - pipeline_sender: queued::PipelineInnerSender) - -> Result, Error> - where VatId: 'static + fn from_results_inner( + results_inner: Result, Error>, + call_status: Result<(), Error>, + pipeline_sender: queued::PipelineInnerSender, + ) -> Result, Error> + where + VatId: 'static, { match results_inner { Err(e) => { @@ -2167,24 +2457,31 @@ impl ResultsDone { } Ok(mut results_inner) => { results_inner.ensure_initialized(); - let ResultsInner { connection_state, variant, - answer_id, finish_received, .. } = results_inner; + let ResultsInner { + connection_state, + variant, + answer_id, + finish_received, + .. + } = results_inner; match variant { None => unreachable!(), Some(ResultsVariant::Rpc(mut message, cap_table)) => { match (finish_received.get(), call_status) { (true, _) => { - let hook = Box::new(ResultsDone::rpc(Rc::new(message.take()), cap_table)) - as Box; - pipeline_sender.complete(Box::new( - local::Pipeline::new(hook.clone()))); + let hook = + Box::new(ResultsDone::rpc(Rc::new(message.take()), cap_table)) + as Box; + pipeline_sender + .complete(Box::new(local::Pipeline::new(hook.clone()))); // Send a Canceled return. match connection_state.connection.borrow_mut().as_mut() { Ok(ref mut connection) => { let mut message = connection.new_outgoing_message(50); // XXX size hint { - let root: message::Builder = message.get_body()?.get_as()?; + let root: message::Builder = + message.get_body()?.get_as()?; let mut ret = root.init_return(); ret.set_answer_id(answer_id); ret.set_release_param_caps(false); @@ -2202,19 +2499,19 @@ impl ResultsDone { let exports = { let root: message::Builder = message.get_body()?.get_as()?; match root.which()? { - message::Return(ret) => { - match ret?.which()? { - crate::rpc_capnp::return_::Results(Ok(payload)) => { - ConnectionState::write_descriptors(&connection_state, - &cap_table, - payload) - } - _ => { - unreachable!() - } + message::Return(ret) => match ret?.which()? { + crate::rpc_capnp::return_::Results(Ok(payload)) => { + ConnectionState::write_descriptors( + &connection_state, + &cap_table, + payload, + ) } - } - _ => { + _ => { + unreachable!() + } + }, + _ => { unreachable!() } } @@ -2222,9 +2519,10 @@ impl ResultsDone { let (_promise, m) = message.send(); connection_state.answer_has_sent_return(answer_id, exports); - let hook = Box::new(ResultsDone::rpc(m, cap_table)) as Box; - pipeline_sender.complete(Box::new( - local::Pipeline::new(hook.clone()))); + let hook = Box::new(ResultsDone::rpc(m, cap_table)) + as Box; + pipeline_sender + .complete(Box::new(local::Pipeline::new(hook.clone()))); Ok(hook) } (false, Err(e)) => { @@ -2233,7 +2531,8 @@ impl ResultsDone { Ok(ref mut connection) => { let mut message = connection.new_outgoing_message(50); // XXX size hint { - let root: message::Builder = message.get_body()?.get_as()?; + let root: message::Builder = + message.get_body()?.get_as()?; let mut ret = root.init_return(); ret.set_answer_id(answer_id); ret.set_release_param_caps(false); @@ -2246,8 +2545,8 @@ impl ResultsDone { } connection_state.answer_has_sent_return(answer_id, Vec::new()); - pipeline_sender.complete(Box::new( - crate::broken::Pipeline::new(e.clone()))); + pipeline_sender + .complete(Box::new(crate::broken::Pipeline::new(e.clone()))); Err(e) } @@ -2256,7 +2555,8 @@ impl ResultsDone { Some(ResultsVariant::LocallyRedirected(results_done, cap_table)) => { let hook = Box::new(ResultsDone::redirected(results_done, cap_table)) as Box; - pipeline_sender.complete(Box::new(crate::local::Pipeline::new(hook.clone()))); + pipeline_sender + .complete(Box::new(crate::local::Pipeline::new(hook.clone()))); Ok(hook) } } @@ -2264,19 +2564,19 @@ impl ResultsDone { } } - fn rpc(message: Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, - cap_table: Vec>>) - -> ResultsDone - { + fn rpc( + message: Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, + cap_table: Vec>>, + ) -> ResultsDone { ResultsDone { inner: Rc::new(ResultsDoneVariant::Rpc(message, cap_table)), } } - fn redirected(message: ::capnp::message::Builder<::capnp::message::HeapAllocator>, - cap_table: Vec>>) - -> ResultsDone - { + fn redirected( + message: ::capnp::message::Builder<::capnp::message::HeapAllocator>, + cap_table: Vec>>, + ) -> ResultsDone { ResultsDone { inner: Rc::new(ResultsDoneVariant::LocallyRedirected(message, cap_table)), } @@ -2285,7 +2585,9 @@ impl ResultsDone { impl ResultsDoneHook for ResultsDone { fn add_ref(&self) -> Box { - Box::new(ResultsDone { inner: self.inner.clone() }) + Box::new(ResultsDone { + inner: self.inner.clone(), + }) } fn get(&self) -> ::capnp::Result { use ::capnp::traits::Imbue; @@ -2293,19 +2595,17 @@ impl ResultsDoneHook for ResultsDone { ResultsDoneVariant::Rpc(ref message, ref cap_table) => { let root: message::Reader = message.get_root_as_reader()?; match root.which()? { - message::Return(ret) => { - match ret?.which()? { - crate::rpc_capnp::return_::Results(payload) => { - let mut content = payload?.get_content(); - content.imbue(cap_table); - Ok(content) - } - _ => { - unreachable!() - } + message::Return(ret) => match ret?.which()? { + crate::rpc_capnp::return_::Results(payload) => { + let mut content = payload?.get_content(); + content.imbue(cap_table); + Ok(content) } - } - _ => { + _ => { + unreachable!() + } + }, + _ => { unreachable!() } } @@ -2319,54 +2619,61 @@ impl ResultsDoneHook for ResultsDone { } } -enum ClientVariant where VatId: 'static { +enum ClientVariant +where + VatId: 'static, +{ Import(Rc>>), Pipeline(Rc>>), Promise(Rc>>), __NoIntercept(()), } -struct Client where VatId: 'static { +struct Client +where + VatId: 'static, +{ connection_state: Rc>, variant: ClientVariant, } -enum WeakClientVariant where VatId: 'static { +enum WeakClientVariant +where + VatId: 'static, +{ Import(Weak>>), Pipeline(Weak>>), Promise(Weak>>), __NoIntercept(()), } -struct WeakClient where VatId: 'static { +struct WeakClient +where + VatId: 'static, +{ connection_state: Weak>, variant: WeakClientVariant, } -impl WeakClient where VatId: 'static { +impl WeakClient +where + VatId: 'static, +{ fn upgrade(&self) -> Option> { let variant = match self.variant { - WeakClientVariant::Import(ref ic) => { - match ic.upgrade() { - Some(ic) => ClientVariant::Import(ic), - None => return None, - } - } - WeakClientVariant::Pipeline(ref pc) => { - match pc.upgrade() { - Some(pc) => ClientVariant::Pipeline(pc), - None => return None, - } - } - WeakClientVariant::Promise(ref pc) => { - match pc.upgrade() { - Some(pc) => ClientVariant::Promise(pc), - None => return None, - } - } - WeakClientVariant::__NoIntercept(()) => { - ClientVariant::__NoIntercept(()) - } + WeakClientVariant::Import(ref ic) => match ic.upgrade() { + Some(ic) => ClientVariant::Import(ic), + None => return None, + }, + WeakClientVariant::Pipeline(ref pc) => match pc.upgrade() { + Some(pc) => ClientVariant::Pipeline(pc), + None => return None, + }, + WeakClientVariant::Promise(ref pc) => match pc.upgrade() { + Some(pc) => ClientVariant::Promise(pc), + None => return None, + }, + WeakClientVariant::__NoIntercept(()) => ClientVariant::__NoIntercept(()), }; let state = match self.connection_state.upgrade() { Some(s) => s, @@ -2379,7 +2686,10 @@ impl WeakClient where VatId: 'static { } } -struct ImportClient where VatId: 'static { +struct ImportClient +where + VatId: 'static, +{ connection_state: Rc>, import_id: ImportId, @@ -2387,12 +2697,15 @@ struct ImportClient where VatId: 'static { remote_ref_count: u32, } -impl Drop for ImportClient { +impl Drop for ImportClient { fn drop(&mut self) { let connection_state = self.connection_state.clone(); - assert!(connection_state.client_downcast_map.borrow_mut() - .remove(&((self) as *const _ as usize)).is_some()); + assert!(connection_state + .client_downcast_map + .borrow_mut() + .remove(&((self) as *const _ as usize)) + .is_some()); // Remove self from the import table, if the table is still pointing at us. let mut remove = false; @@ -2405,7 +2718,11 @@ impl Drop for ImportClient { } if remove { - connection_state.imports.borrow_mut().slots.remove(&self.import_id); + connection_state + .imports + .borrow_mut() + .slots + .remove(&self.import_id); } // Send a message releasing our remote references. @@ -2426,9 +2743,14 @@ impl Drop for ImportClient { } } -impl ImportClient where VatId: 'static { - fn new(connection_state: &Rc>, import_id: ImportId) - -> Rc>> { +impl ImportClient +where + VatId: 'static, +{ + fn new( + connection_state: &Rc>, + import_id: ImportId, + ) -> Rc>> { Rc::new(RefCell::new(ImportClient { connection_state: connection_state.clone(), import_id, @@ -2441,7 +2763,7 @@ impl ImportClient where VatId: 'static { } } -impl From>>> for Client { +impl From>>> for Client { fn from(client: Rc>>) -> Client { let connection_state = client.borrow().connection_state.clone(); Client::new(&connection_state, ClientVariant::Import(client)) @@ -2449,16 +2771,24 @@ impl From>>> for Client { } /// A `ClientHook` representing a pipelined promise. Always wrapped in `PromiseClient`. -struct PipelineClient where VatId: 'static { +struct PipelineClient +where + VatId: 'static, +{ connection_state: Rc>, question_ref: Rc>>, ops: Vec, } -impl PipelineClient where VatId: 'static { - fn new(connection_state: &Rc>, - question_ref: Rc>>, - ops: Vec) -> Rc>> { +impl PipelineClient +where + VatId: 'static, +{ + fn new( + connection_state: &Rc>, + question_ref: Rc>>, + ops: Vec, + ) -> Rc>> { Rc::new(RefCell::new(PipelineClient { connection_state: connection_state.clone(), question_ref, @@ -2467,24 +2797,30 @@ impl PipelineClient where VatId: 'static { } } -impl From>>> for Client { +impl From>>> for Client { fn from(client: Rc>>) -> Client { let connection_state = client.borrow().connection_state.clone(); Client::new(&connection_state, ClientVariant::Pipeline(client)) } } -impl Drop for PipelineClient { +impl Drop for PipelineClient { fn drop(&mut self) { - assert!(self.connection_state.client_downcast_map.borrow_mut() - .remove(&((self) as *const _ as usize)).is_some()); + assert!(self + .connection_state + .client_downcast_map + .borrow_mut() + .remove(&((self) as *const _ as usize)) + .is_some()); } } - /// A `ClientHook` that initially wraps one client and then, later on, redirects /// to some other client. -struct PromiseClient where VatId: 'static { +struct PromiseClient +where + VatId: 'static, +{ connection_state: Rc>, is_resolved: bool, cap: Box, @@ -2493,10 +2829,12 @@ struct PromiseClient where VatId: 'static { resolution_waiters: crate::sender_queue::SenderQueue<(), Box>, } -impl PromiseClient { - fn new(connection_state: &Rc>, - initial: Box, - import_id: Option) -> Rc>> { +impl PromiseClient { + fn new( + connection_state: &Rc>, + initial: Box, + import_id: Option, + ) -> Rc>> { Rc::new(RefCell::new(PromiseClient { connection_state: connection_state.clone(), is_resolved: false, @@ -2515,23 +2853,32 @@ impl PromiseClient { let connection_state = self.connection_state.clone(); let is_connected = connection_state.connection.borrow().is_ok(); let replacement_brand = replacement.get_brand(); - if replacement_brand != connection_state.get_brand() && - self.received_call && !is_error && is_connected + if replacement_brand != connection_state.get_brand() + && self.received_call + && !is_error + && is_connected { // The new capability is hosted locally, not on the remote machine. And, we had made calls // to the promise. We need to make sure those calls echo back to us before we allow new // calls to go directly to the local capability, so we need to set a local embargo and send // a `Disembargo` to echo through the peer. - let (fulfiller, promise) = oneshot::channel::>(); - let promise = promise.map_err(crate::canceled_to_error).and_then(|v| future::ready(v)); + let (fulfiller, promise) = oneshot::channel::>(); + let promise = promise + .map_err(crate::canceled_to_error) + .and_then(|v| future::ready(v)); let embargo = Embargo::new(fulfiller); let embargo_id = connection_state.embargoes.borrow_mut().push(embargo); - let mut message = connection_state.new_outgoing_message(50).expect("no connection?"); // XXX size hint + let mut message = connection_state + .new_outgoing_message(50) + .expect("no connection?"); // XXX size hint { let root: message::Builder = message.get_body().unwrap().init_as(); let mut disembargo = root.init_disembargo(); - disembargo.reborrow().init_context().set_sender_loopback(embargo_id); + disembargo + .reborrow() + .init_context() + .set_sender_loopback(embargo_id); let target = disembargo.init_target(); let redirect = connection_state.write_target(&*self.cap, target); @@ -2574,7 +2921,7 @@ impl PromiseClient { } } -impl Drop for PromiseClient { +impl Drop for PromiseClient { fn drop(&mut self) { let self_ptr = (self) as *const _ as usize; @@ -2599,21 +2946,27 @@ impl Drop for PromiseClient { } } - assert!(self.connection_state.client_downcast_map.borrow_mut().remove(&self_ptr).is_some()); + assert!(self + .connection_state + .client_downcast_map + .borrow_mut() + .remove(&self_ptr) + .is_some()); } } -impl From>>> for Client { +impl From>>> for Client { fn from(client: Rc>>) -> Client { let connection_state = client.borrow().connection_state.clone(); Client::new(&connection_state, ClientVariant::Promise(client)) } } -impl Client { - fn new(connection_state: &Rc>, variant: ClientVariant) - -> Client - { +impl Client { + fn new( + connection_state: &Rc>, + variant: ClientVariant, + ) -> Client { let client = Client { connection_state: connection_state.clone(), variant, @@ -2621,7 +2974,10 @@ impl Client { let weak = client.downgrade(); // XXX arguably, this should go in each of the variant's constructors. - connection_state.client_downcast_map.borrow_mut().insert(client.get_ptr(), weak); + connection_state + .client_downcast_map + .borrow_mut() + .insert(client.get_ptr(), weak); client } fn downgrade(&self) -> WeakClient { @@ -2645,18 +3001,17 @@ impl Client { } } - fn from_ptr(ptr: usize, connection_state: &ConnectionState) - -> Option> - { - match connection_state.client_downcast_map.borrow().get(&ptr){ + fn from_ptr(ptr: usize, connection_state: &ConnectionState) -> Option> { + match connection_state.client_downcast_map.borrow().get(&ptr) { Some(c) => c.upgrade(), None => None, } } - fn write_target(&self, mut target: crate::rpc_capnp::message_target::Builder) - -> Option> - { + fn write_target( + &self, + mut target: crate::rpc_capnp::message_target::Builder, + ) -> Option> { match self.variant { ClientVariant::Import(ref import_client) => { target.set_imported_cap(import_client.borrow().import_id); @@ -2666,11 +3021,15 @@ impl Client { let mut builder = target.init_promised_answer(); let question_ref = &pipeline_client.borrow().question_ref; builder.set_question_id(question_ref.borrow().id); - let mut transform = builder.init_transform(pipeline_client.borrow().ops.len() as u32); - for idx in 0 .. pipeline_client.borrow().ops.len() { + let mut transform = + builder.init_transform(pipeline_client.borrow().ops.len() as u32); + for idx in 0..pipeline_client.borrow().ops.len() { match pipeline_client.borrow().ops[idx] { ::capnp::private::capability::PipelineOp::GetPointerField(ordinal) => { - transform.reborrow().get(idx as u32).set_get_pointer_field(ordinal); + transform + .reborrow() + .get(idx as u32) + .set_get_pointer_field(ordinal); } _ => {} } @@ -2679,8 +3038,8 @@ impl Client { } ClientVariant::Promise(ref promise_client) => { promise_client.borrow_mut().received_call = true; - self.connection_state.write_target( - &*promise_client.borrow().cap, target) + self.connection_state + .write_target(&*promise_client.borrow().cap, target) } _ => { unimplemented!() @@ -2698,11 +3057,15 @@ impl Client { let mut promised_answer = descriptor.init_receiver_answer(); let question_ref = &pipeline_client.borrow().question_ref; promised_answer.set_question_id(question_ref.borrow().id); - let mut transform = promised_answer.init_transform(pipeline_client.borrow().ops.len() as u32); - for idx in 0 .. pipeline_client.borrow().ops.len() { + let mut transform = + promised_answer.init_transform(pipeline_client.borrow().ops.len() as u32); + for idx in 0..pipeline_client.borrow().ops.len() { match pipeline_client.borrow().ops[idx] { ::capnp::private::capability::PipelineOp::GetPointerField(ordinal) => { - transform.reborrow().get(idx as u32).set_get_pointer_field(ordinal); + transform + .reborrow() + .get(idx as u32) + .set_get_pointer_field(ordinal); } _ => {} } @@ -2713,9 +3076,12 @@ impl Client { ClientVariant::Promise(ref promise_client) => { promise_client.borrow_mut().received_call = true; - ConnectionState::write_descriptor(&self.connection_state.clone(), - &promise_client.borrow().cap.clone(), - descriptor).unwrap() + ConnectionState::write_descriptor( + &self.connection_state.clone(), + &promise_client.borrow().cap.clone(), + descriptor, + ) + .unwrap() } _ => { unimplemented!() @@ -2724,7 +3090,7 @@ impl Client { } } -impl Clone for Client { +impl Clone for Client { fn clone(&self) -> Client { let variant = match self.variant { ClientVariant::Import(ref import_client) => { @@ -2740,47 +3106,52 @@ impl Clone for Client { unimplemented!() } }; - Client { connection_state: self.connection_state.clone(), variant} + Client { + connection_state: self.connection_state.clone(), + variant, + } } } -impl ClientHook for Client { +impl ClientHook for Client { fn add_ref(&self) -> Box { Box::new(self.clone()) } - fn new_call(&self, interface_id: u64, method_id: u16, - size_hint: Option<::capnp::MessageSize>) - -> ::capnp::capability::Request - { + fn new_call( + &self, + interface_id: u64, + method_id: u16, + size_hint: Option<::capnp::MessageSize>, + ) -> ::capnp::capability::Request { let request: Box = - match Request::new(self.connection_state.clone(), size_hint, self.clone()) - { - Ok(mut request) => { - { - let mut call_builder = request.init_call(); - call_builder.set_interface_id(interface_id); - call_builder.set_method_id(method_id); + match Request::new(self.connection_state.clone(), size_hint, self.clone()) { + Ok(mut request) => { + { + let mut call_builder = request.init_call(); + call_builder.set_interface_id(interface_id); + call_builder.set_method_id(method_id); + } + Box::new(request) } - Box::new(request) - } - Err(e) => { - Box::new(broken::Request::new(e, None)) - } - }; + Err(e) => Box::new(broken::Request::new(e, None)), + }; ::capnp::capability::Request::new(request) } - fn call(&self, interface_id: u64, method_id: u16, params: Box, - mut results: Box) - -> Promise<(), Error> - { + fn call( + &self, + interface_id: u64, + method_id: u16, + params: Box, + mut results: Box, + ) -> Promise<(), Error> { // Implement call() by copying params and results messages. let maybe_request = params.get().and_then(|p| { - let mut request = p.target_size().and_then(|s| { - Ok(self.new_call(interface_id, method_id, Some(s))) - })?; + let mut request = p + .target_size() + .and_then(|s| Ok(self.new_call(interface_id, method_id, Some(s))))?; request.get().set_as(p)?; Ok(request) }); @@ -2829,12 +3200,8 @@ impl ClientHook for Client { fn get_resolved(&self) -> Option> { match self.variant { - ClientVariant::Import(ref _import_client) => { - None - } - ClientVariant::Pipeline(ref _pipeline_client) => { - None - } + ClientVariant::Import(ref _import_client) => None, + ClientVariant::Pipeline(ref _pipeline_client) => None, ClientVariant::Promise(ref promise_client) => { if promise_client.borrow().is_resolved { Some(promise_client.borrow().cap.clone()) @@ -2850,12 +3217,8 @@ impl ClientHook for Client { fn when_more_resolved(&self) -> Option, Error>> { match self.variant { - ClientVariant::Import(ref _import_client) => { - None - } - ClientVariant::Pipeline(ref _pipeline_client) => { - None - } + ClientVariant::Import(ref _import_client) => None, + ClientVariant::Pipeline(ref _pipeline_client) => None, ClientVariant::Promise(ref promise_client) => { Some(promise_client.borrow_mut().resolution_waiters.push(())) } @@ -2871,17 +3234,14 @@ impl ClientHook for Client { } pub(crate) fn default_when_resolved_impl(client: &C) -> Promise<(), Error> - where C: ClientHook +where + C: ClientHook, { match client.when_more_resolved() { Some(promise) => { - Promise::from_future(promise.and_then(|resolution| { - resolution.when_resolved() - })) - } - None => { - Promise::ok(()) + Promise::from_future(promise.and_then(|resolution| resolution.when_resolved())) } + None => Promise::ok(()), } } @@ -2899,7 +3259,9 @@ impl SingleCapPipeline { impl PipelineHook for SingleCapPipeline { fn add_ref(&self) -> Box { - Box::new(SingleCapPipeline {cap: self.cap.clone() }) + Box::new(SingleCapPipeline { + cap: self.cap.clone(), + }) } fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box { if ops.is_empty() { diff --git a/capnp-rpc/src/sender_queue.rs b/capnp-rpc/src/sender_queue.rs index 09b49df02..8349a7f59 100644 --- a/capnp-rpc/src/sender_queue.rs +++ b/capnp-rpc/src/sender_queue.rs @@ -19,8 +19,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use futures::{FutureExt, TryFutureExt}; use futures::channel::oneshot; +use futures::{FutureExt, TryFutureExt}; use std::cell::RefCell; use std::rc::{Rc, Weak}; @@ -31,7 +31,9 @@ use capnp::Error; use std::collections::BTreeMap; struct Inner - where In: 'static, Out: 'static +where + In: 'static, + Out: 'static, { next_id: u64, map: BTreeMap)>, @@ -40,20 +42,26 @@ struct Inner /// A queue representing tasks that consume input of type `In` and produce output of /// type `Out`. pub struct SenderQueue - where In: 'static, Out: 'static +where + In: 'static, + Out: 'static, { inner: Rc>>, } pub struct Remover - where In: 'static, Out: 'static +where + In: 'static, + Out: 'static, { id: u64, inner: Weak>>, } -impl Drop for Remover - where In: 'static, Out: 'static +impl Drop for Remover +where + In: 'static, + Out: 'static, { fn drop(&mut self) { match self.inner.upgrade() { @@ -66,7 +74,11 @@ impl Drop for Remover } } -impl SenderQueue where In: 'static, Out: 'static { +impl SenderQueue +where + In: 'static, + Out: 'static, +{ pub fn new() -> SenderQueue { SenderQueue { inner: Rc::new(RefCell::new(Inner { @@ -81,7 +93,11 @@ impl SenderQueue where In: 'static, Out: 'static { /// is dropped, then `value` is removed from the queue. pub fn push(&mut self, value: In) -> Promise { let weak_inner = Rc::downgrade(&self.inner); - let Inner { ref mut next_id, ref mut map, .. } = *self.inner.borrow_mut(); + let Inner { + ref mut next_id, + ref mut map, + .. + } = *self.inner.borrow_mut(); let (tx, rx) = oneshot::channel(); map.insert(*next_id, (value, tx)); @@ -92,39 +108,53 @@ impl SenderQueue where In: 'static, Out: 'static { *next_id += 1; - Promise::from_future(rx.map_err(|_| Error::failed("SenderQueue canceled".into())).map(move |out| { - drop(remover); - out - })) + Promise::from_future( + rx.map_err(|_| Error::failed("SenderQueue canceled".into())) + .map(move |out| { + drop(remover); + out + }), + ) } /// Pushes `values` to the queue. pub fn push_detach(&mut self, value: In) { - let Inner { ref mut next_id, ref mut map, .. } = *self.inner.borrow_mut(); + let Inner { + ref mut next_id, + ref mut map, + .. + } = *self.inner.borrow_mut(); let (tx, _rx) = oneshot::channel(); map.insert(*next_id, (value, tx)); *next_id += 1; } - pub fn drain(&mut self) -> Drain { - let Inner { ref mut next_id, ref mut map, .. } = *self.inner.borrow_mut(); + let Inner { + ref mut next_id, + ref mut map, + .. + } = *self.inner.borrow_mut(); *next_id = 0; let map = ::std::mem::replace(map, BTreeMap::new()); Drain { - iter: map.into_iter() + iter: map.into_iter(), } } } pub struct Drain -where In: 'static, Out: 'static +where + In: 'static, + Out: 'static, { iter: ::std::collections::btree_map::IntoIter)>, } -impl ::std::iter::Iterator for Drain - where In: 'static, Out: 'static +impl ::std::iter::Iterator for Drain +where + In: 'static, + Out: 'static, { type Item = (In, oneshot::Sender); fn next(&mut self) -> Option { diff --git a/capnp-rpc/src/split.rs b/capnp-rpc/src/split.rs index d5c363f61..69f851d5e 100644 --- a/capnp-rpc/src/split.rs +++ b/capnp-rpc/src/split.rs @@ -22,17 +22,28 @@ use futures::{Future, FutureExt}; use std::cell::RefCell; -use std::rc::{Rc}; +use std::rc::Rc; -pub fn split(f: F) -> (impl Future>, - impl Future>) - where F: Future>, - E: Clone, +pub fn split( + f: F, +) -> ( + impl Future>, + impl Future>, +) +where + F: Future>, + E: Clone, { - let shared = f.map(|r| { - let (v1, v2) = r?; - Ok(Rc::new(RefCell::new((Some(v1), Some(v2))))) - }).shared(); - (shared.clone().map(|r| Ok::(r?.borrow_mut().0.take().unwrap())), - shared.map(|r| Ok::(r?.borrow_mut().1.take().unwrap()))) + let shared = f + .map(|r| { + let (v1, v2) = r?; + Ok(Rc::new(RefCell::new((Some(v1), Some(v2))))) + }) + .shared(); + ( + shared + .clone() + .map(|r| Ok::(r?.borrow_mut().0.take().unwrap())), + shared.map(|r| Ok::(r?.borrow_mut().1.take().unwrap())), + ) } diff --git a/capnp-rpc/src/task_set.rs b/capnp-rpc/src/task_set.rs index 6fcd99e33..68edea5de 100644 --- a/capnp-rpc/src/task_set.rs +++ b/capnp-rpc/src/task_set.rs @@ -18,46 +18,44 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +use futures::channel::mpsc; +use futures::stream::FuturesUnordered; +use futures::{Future, FutureExt, Stream}; use std::pin::Pin; use std::task::{Context, Poll}; -use futures::{Future, FutureExt, Stream}; -use futures::stream::FuturesUnordered; -use futures::channel::mpsc; -use std::cell::{RefCell}; +use std::cell::RefCell; use std::rc::Rc; enum EnqueuedTask { - Task(Pin>>>), + Task(Pin>>>), Terminate(Result<(), E>), } enum TaskInProgress { - Task(Pin>>), + Task(Pin>>), Terminate(Option>), } -impl Unpin for TaskInProgress {} +impl Unpin for TaskInProgress {} enum TaskDone { Continue, Terminate(Result<(), E>), } -impl Future for TaskInProgress { +impl Future for TaskInProgress { type Output = TaskDone; fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { match *self { - TaskInProgress::Terminate(ref mut r) => - Poll::Ready(TaskDone::Terminate(r.take().unwrap())), - TaskInProgress::Task(ref mut f) => { - match f.as_mut().poll(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(()) => Poll::Ready(TaskDone::Continue), - } + TaskInProgress::Terminate(ref mut r) => { + Poll::Ready(TaskDone::Terminate(r.take().unwrap())) } - + TaskInProgress::Task(ref mut f) => match f.as_mut().poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(()) => Poll::Ready(TaskDone::Continue), + }, } } } @@ -69,10 +67,14 @@ pub struct TaskSet { reaper: Rc>>>, } -impl TaskSet where E: 'static { - pub fn new(reaper: Box>) - -> (TaskSetHandle, TaskSet) - where E: 'static, E: ::std::fmt::Debug, +impl TaskSet +where + E: 'static, +{ + pub fn new(reaper: Box>) -> (TaskSetHandle, TaskSet) + where + E: 'static, + E: ::std::fmt::Debug, { let (sender, receiver) = mpsc::unbounded(); @@ -84,11 +86,10 @@ impl TaskSet where E: 'static { // If the FuturesUnordered ever gets empty, its stream will terminate, which // is not what we want. So we make sure there is always at least one future in it. - set.in_progress.push(TaskInProgress::Task(Box::pin(::futures::future::pending()))); + set.in_progress + .push(TaskInProgress::Task(Box::pin(::futures::future::pending()))); - let handle = TaskSetHandle { - sender, - }; + let handle = TaskSetHandle { sender }; (handle, set) } @@ -96,12 +97,16 @@ impl TaskSet where E: 'static { #[derive(Clone)] pub struct TaskSetHandle { - sender: mpsc::UnboundedSender> + sender: mpsc::UnboundedSender>, } -impl TaskSetHandle where E: 'static { +impl TaskSetHandle +where + E: 'static, +{ pub fn add(&mut self, f: F) - where F: Future> + 'static + where + F: Future> + 'static, { let _ = self.sender.unbounded_send(EnqueuedTask::Task(Box::pin(f))); } @@ -111,18 +116,29 @@ impl TaskSetHandle where E: 'static { } } -pub trait TaskReaper where E: 'static +pub trait TaskReaper +where + E: 'static, { fn task_succeeded(&mut self) {} fn task_failed(&mut self, error: E); } -impl Future for TaskSet where E: 'static { - type Output = Result<(),E>; +impl Future for TaskSet +where + E: 'static, +{ + type Output = Result<(), E>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { let mut enqueued_stream_complete = false; - if let TaskSet { enqueued: Some(ref mut enqueued), ref mut in_progress, ref reaper, ..} = self.as_mut().get_mut() { + if let TaskSet { + enqueued: Some(ref mut enqueued), + ref mut in_progress, + ref reaper, + .. + } = self.as_mut().get_mut() + { loop { match Pin::new(&mut *enqueued).poll_next(cx) { Poll::Pending => break, @@ -135,19 +151,15 @@ impl Future for TaskSet where E: 'static { } Poll::Ready(Some(EnqueuedTask::Task(f))) => { let reaper = Rc::downgrade(reaper); - in_progress.push( - TaskInProgress::Task(Box::pin( - f.map(move |r| { - match reaper.upgrade() { - None => (), // TaskSet must have been dropped. - Some(rc_reaper) => { - match r { - Ok(()) => rc_reaper.borrow_mut().task_succeeded(), - Err(e) => rc_reaper.borrow_mut().task_failed(e), - } - } - } - })))); + in_progress.push(TaskInProgress::Task(Box::pin(f.map(move |r| { + match reaper.upgrade() { + None => (), // TaskSet must have been dropped. + Some(rc_reaper) => match r { + Ok(()) => rc_reaper.borrow_mut().task_succeeded(), + Err(e) => rc_reaper.borrow_mut().task_failed(e), + }, + } + })))); } } } @@ -159,15 +171,12 @@ impl Future for TaskSet where E: 'static { loop { match Stream::poll_next(Pin::new(&mut self.in_progress), cx) { Poll::Pending => return Poll::Pending, - Poll::Ready(v) => { - match v { - None => return Poll::Ready(Ok(())), - Some(TaskDone::Continue) => (), - Some(TaskDone::Terminate(Ok(()))) => - return Poll::Ready(Ok(())), - Some(TaskDone::Terminate(Err(e))) => return Poll::Ready(Err(e)), - } - } + Poll::Ready(v) => match v { + None => return Poll::Ready(Ok(())), + Some(TaskDone::Continue) => (), + Some(TaskDone::Terminate(Ok(()))) => return Poll::Ready(Ok(())), + Some(TaskDone::Terminate(Err(e))) => return Poll::Ready(Err(e)), + }, } } } diff --git a/capnp-rpc/src/twoparty.rs b/capnp-rpc/src/twoparty.rs index 66851e7ec..65917e167 100644 --- a/capnp-rpc/src/twoparty.rs +++ b/capnp-rpc/src/twoparty.rs @@ -21,10 +21,10 @@ //! An implementation of `VatNetwork` for the common case of a client-server connection. -use capnp::message::ReaderOptions; use capnp::capability::Promise; -use futures::{AsyncRead, AsyncWrite, FutureExt, TryFutureExt}; +use capnp::message::ReaderOptions; use futures::channel::oneshot; +use futures::{AsyncRead, AsyncWrite, FutureExt, TryFutureExt}; use std::cell::RefCell; use std::rc::{Rc, Weak}; @@ -36,7 +36,9 @@ struct IncomingMessage { } impl IncomingMessage { - pub fn new(message: ::capnp::message::Reader) -> IncomingMessage { + pub fn new( + message: ::capnp::message::Reader, + ) -> IncomingMessage { IncomingMessage { message } } } @@ -61,25 +63,30 @@ impl crate::OutgoingMessage for OutgoingMessage { self.message.get_root_as_reader() } - fn send(self: Box) - -> - (Promise>, ::capnp::Error>, - Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>) - { + fn send( + self: Box, + ) -> ( + Promise>, ::capnp::Error>, + Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, + ) { let tmp = *self; - let OutgoingMessage {message, mut sender} = tmp; + let OutgoingMessage { + message, + mut sender, + } = tmp; let m = Rc::new(message); (Promise::from_future(sender.send(m.clone())), m) } - fn take(self: Box) - -> ::capnp::message::Builder<::capnp::message::HeapAllocator> - { + fn take(self: Box) -> ::capnp::message::Builder<::capnp::message::HeapAllocator> { self.message } } -struct ConnectionInner where T: AsyncRead + 'static { +struct ConnectionInner +where + T: AsyncRead + 'static, +{ input_stream: Rc>>, sender: ::capnp_futures::Sender>>, side: crate::rpc_twoparty_capnp::Side, @@ -87,11 +94,17 @@ struct ConnectionInner where T: AsyncRead + 'static { on_disconnect_fulfiller: Option>, } -struct Connection where T: AsyncRead + 'static { +struct Connection +where + T: AsyncRead + 'static, +{ inner: Rc>>, } -impl Drop for ConnectionInner where T: AsyncRead { +impl Drop for ConnectionInner +where + T: AsyncRead, +{ fn drop(&mut self) { let maybe_fulfiller = ::std::mem::replace(&mut self.on_disconnect_fulfiller, None); match maybe_fulfiller { @@ -103,43 +116,52 @@ impl Drop for ConnectionInner where T: AsyncRead { } } -impl Connection where T: AsyncRead { - fn new(input_stream: T, - sender: ::capnp_futures::Sender>>, - side: crate::rpc_twoparty_capnp::Side, - receive_options: ReaderOptions, - on_disconnect_fulfiller: oneshot::Sender<()>, - ) -> Connection - { - +impl Connection +where + T: AsyncRead, +{ + fn new( + input_stream: T, + sender: ::capnp_futures::Sender< + Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, + >, + side: crate::rpc_twoparty_capnp::Side, + receive_options: ReaderOptions, + on_disconnect_fulfiller: oneshot::Sender<()>, + ) -> Connection { Connection { - inner: Rc::new(RefCell::new( - ConnectionInner { - input_stream: Rc::new(RefCell::new(Some(input_stream))), - sender, - side, - receive_options, - on_disconnect_fulfiller: Some(on_disconnect_fulfiller), - })), + inner: Rc::new(RefCell::new(ConnectionInner { + input_stream: Rc::new(RefCell::new(Some(input_stream))), + sender, + side, + receive_options, + on_disconnect_fulfiller: Some(on_disconnect_fulfiller), + })), } } } -impl crate::Connection for Connection - where T: AsyncRead + Unpin +impl crate::Connection for Connection +where + T: AsyncRead + Unpin, { fn get_peer_vat_id(&self) -> crate::rpc_twoparty_capnp::Side { self.inner.borrow().side } - fn new_outgoing_message(&mut self, _first_segment_word_size: u32) -> Box { + fn new_outgoing_message( + &mut self, + _first_segment_word_size: u32, + ) -> Box { Box::new(OutgoingMessage { message: ::capnp::message::Builder::new_default(), sender: self.inner.borrow().sender.clone(), }) } - fn receive_incoming_message(&mut self) -> Promise>, ::capnp::Error> { + fn receive_incoming_message( + &mut self, + ) -> Promise>, ::capnp::Error> { let inner = self.inner.borrow_mut(); let maybe_input_stream = ::std::mem::replace(&mut *inner.input_stream.borrow_mut(), None); @@ -148,15 +170,20 @@ impl crate::Connection for Connection Some(mut s) => { let receive_options = inner.receive_options; Promise::from_future(async move { - let maybe_message = ::capnp_futures::serialize::try_read_message(&mut s, receive_options).await?; + let maybe_message = + ::capnp_futures::serialize::try_read_message(&mut s, receive_options) + .await?; *return_it_here.borrow_mut() = Some(s); - Ok(maybe_message.map(|message| - Box::new(IncomingMessage::new(message)) as Box)) + Ok(maybe_message.map(|message| { + Box::new(IncomingMessage::new(message)) as Box + })) }) } None => { - Promise::err(::capnp::Error::failed("this should not be possible".to_string())) - // unreachable!(), + Promise::err(::capnp::Error::failed( + "this should not be possible".to_string(), + )) + // unreachable!(), } } } @@ -167,7 +194,10 @@ impl crate::Connection for Connection } /// A vat network with two parties, the client and the server. -pub struct VatNetwork where T: AsyncRead + 'static + Unpin { +pub struct VatNetwork +where + T: AsyncRead + 'static + Unpin, +{ // connection handle that we will return on accept() connection: Option>, @@ -178,7 +208,10 @@ pub struct VatNetwork where T: AsyncRead + 'static + Unpin { side: crate::rpc_twoparty_capnp::Side, } -impl VatNetwork where T: AsyncRead + Unpin { +impl VatNetwork +where + T: AsyncRead + Unpin, +{ /// Creates a new two-party vat network that will receive data on `input_stream` and send data on /// `output_stream`. /// @@ -188,29 +221,35 @@ impl VatNetwork where T: AsyncRead + Unpin { /// will make more sense once we have vat networks with more than two parties. /// /// The options in `receive_options` will be used when reading the messages that come in on `input_stream`. - pub fn new(input_stream: T, - output_stream: U, - side: crate::rpc_twoparty_capnp::Side, - receive_options: ReaderOptions) -> VatNetwork - where U: AsyncWrite + 'static + Unpin, + pub fn new( + input_stream: T, + output_stream: U, + side: crate::rpc_twoparty_capnp::Side, + receive_options: ReaderOptions, + ) -> VatNetwork + where + U: AsyncWrite + 'static + Unpin, { - let (fulfiller, disconnect_promise) = oneshot::channel(); - let disconnect_promise = disconnect_promise - .map_err(|_| ::capnp::Error::disconnected("disconnected".into())); + let disconnect_promise = + disconnect_promise.map_err(|_| ::capnp::Error::disconnected("disconnected".into())); let (execution_driver, sender) = { let (tx, write_queue) = ::capnp_futures::write_queue(output_stream); // Don't use `.join()` here because we need to make sure to wait for `disconnect_promise` to // resolve even if `write_queue` resolves to an error. - (Promise::from_future( - write_queue - .then(move |r| disconnect_promise.then(move |_| futures::future::ready(r)).map_ok(|_| ()))).shared(), - tx) + ( + Promise::from_future(write_queue.then(move |r| { + disconnect_promise + .then(move |_| futures::future::ready(r)) + .map_ok(|_| ()) + })) + .shared(), + tx, + ) }; - let connection = Connection::new(input_stream, sender, side, receive_options, fulfiller); let weak_inner = Rc::downgrade(&connection.inner); VatNetwork { @@ -222,17 +261,18 @@ impl VatNetwork where T: AsyncRead + Unpin { } } -impl crate::VatNetwork for VatNetwork - where T: AsyncRead + Unpin +impl crate::VatNetwork for VatNetwork +where + T: AsyncRead + Unpin, { fn connect(&mut self, host_id: VatId) -> Option>> { if host_id == self.side { None } else { match self.weak_connection_inner.upgrade() { - Some(connection_inner) => { - Some(Box::new(Connection { inner: connection_inner })) - } + Some(connection_inner) => Some(Box::new(Connection { + inner: connection_inner, + })), None => { panic!("tried to reconnect a disconnected twoparty vat network.") } diff --git a/capnp-rpc/test/build.rs b/capnp-rpc/test/build.rs index 3e8075893..db010cb0e 100644 --- a/capnp-rpc/test/build.rs +++ b/capnp-rpc/test/build.rs @@ -1,3 +1,6 @@ fn main() { - ::capnpc::CompilerCommand::new().file("test.capnp").run().unwrap(); + ::capnpc::CompilerCommand::new() + .file("test.capnp") + .run() + .unwrap(); } diff --git a/capnp-rpc/test/impls.rs b/capnp-rpc/test/impls.rs index 2572a83c9..76ce497a4 100644 --- a/capnp-rpc/test/impls.rs +++ b/capnp-rpc/test/impls.rs @@ -19,12 +19,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use crate::test_capnp::{bootstrap, test_handle, test_interface, test_extends, test_pipeline, - test_call_order, test_more_stuff, test_capability_server_set}; +use crate::test_capnp::{ + bootstrap, test_call_order, test_capability_server_set, test_extends, test_handle, + test_interface, test_more_stuff, test_pipeline, +}; - -use capnp::Error; use capnp::capability::Promise; +use capnp::Error; use capnp_rpc::pry; use futures::{FutureExt, TryFutureExt}; @@ -35,73 +36,81 @@ use std::rc::Rc; pub struct Bootstrap; impl bootstrap::Server for Bootstrap { - fn test_interface(&mut self, - _params: bootstrap::TestInterfaceParams, - mut results: bootstrap::TestInterfaceResults) - -> Promise<(), Error> - { + fn test_interface( + &mut self, + _params: bootstrap::TestInterfaceParams, + mut results: bootstrap::TestInterfaceResults, + ) -> Promise<(), Error> { { - results.get().set_cap(capnp_rpc::new_client(TestInterface::new())); + results + .get() + .set_cap(capnp_rpc::new_client(TestInterface::new())); } Promise::ok(()) } - fn test_extends(&mut self, - _params: bootstrap::TestExtendsParams, - mut results: bootstrap::TestExtendsResults) - -> Promise<(), Error> - { + fn test_extends( + &mut self, + _params: bootstrap::TestExtendsParams, + mut results: bootstrap::TestExtendsResults, + ) -> Promise<(), Error> { { results.get().set_cap(capnp_rpc::new_client(TestExtends)); } Promise::ok(()) } - fn test_extends2(&mut self, - _params: bootstrap::TestExtends2Params, - _results: bootstrap::TestExtends2Results) - -> Promise<(), Error> - { + fn test_extends2( + &mut self, + _params: bootstrap::TestExtends2Params, + _results: bootstrap::TestExtends2Results, + ) -> Promise<(), Error> { unimplemented!() } - fn test_pipeline(&mut self, - _params: bootstrap::TestPipelineParams, - mut results: bootstrap::TestPipelineResults) - -> Promise<(), Error> - { + fn test_pipeline( + &mut self, + _params: bootstrap::TestPipelineParams, + mut results: bootstrap::TestPipelineResults, + ) -> Promise<(), Error> { { results.get().set_cap(capnp_rpc::new_client(TestPipeline)); } Promise::ok(()) } - fn test_call_order(&mut self, - _params: bootstrap::TestCallOrderParams, - mut results: bootstrap::TestCallOrderResults) - -> Promise<(), Error> - { + fn test_call_order( + &mut self, + _params: bootstrap::TestCallOrderParams, + mut results: bootstrap::TestCallOrderResults, + ) -> Promise<(), Error> { { - results.get().set_cap(capnp_rpc::new_client(TestCallOrder::new())); + results + .get() + .set_cap(capnp_rpc::new_client(TestCallOrder::new())); } Promise::ok(()) } - fn test_more_stuff(&mut self, - _params: bootstrap::TestMoreStuffParams, - mut results: bootstrap::TestMoreStuffResults) - -> Promise<(), Error> - { + fn test_more_stuff( + &mut self, + _params: bootstrap::TestMoreStuffParams, + mut results: bootstrap::TestMoreStuffResults, + ) -> Promise<(), Error> { { - results.get().set_cap(capnp_rpc::new_client(TestMoreStuff::new())); + results + .get() + .set_cap(capnp_rpc::new_client(TestMoreStuff::new())); } Promise::ok(()) } - fn test_capability_server_set(&mut self, - _params: bootstrap::TestCapabilityServerSetParams, - mut results: bootstrap::TestCapabilityServerSetResults) - -> Promise<(), Error> - { - results.get().set_cap(capnp_rpc::new_client(TestCapabilityServerSet::new())); + fn test_capability_server_set( + &mut self, + _params: bootstrap::TestCapabilityServerSetParams, + mut results: bootstrap::TestCapabilityServerSetResults, + ) -> Promise<(), Error> { + results + .get() + .set_cap(capnp_rpc::new_client(TestCapabilityServerSet::new())); Promise::ok(()) } } @@ -112,7 +121,9 @@ pub struct TestInterface { impl TestInterface { pub fn new() -> TestInterface { - TestInterface { call_count: Rc::new(Cell::new(0)) } + TestInterface { + call_count: Rc::new(Cell::new(0)), + } } pub fn get_call_count(&self) -> Rc> { self.call_count.clone() @@ -123,11 +134,11 @@ impl TestInterface { } impl test_interface::Server for TestInterface { - fn foo(&mut self, - params: test_interface::FooParams, - mut results: test_interface::FooResults) - -> Promise<(), Error> - { + fn foo( + &mut self, + params: test_interface::FooParams, + mut results: test_interface::FooResults, + ) -> Promise<(), Error> { self.increment_call_count(); let params = pry!(params.get()); if params.get_i() != 123 { @@ -143,20 +154,20 @@ impl test_interface::Server for TestInterface { Promise::ok(()) } - fn bar(&mut self, - _params: test_interface::BarParams, - _results: test_interface::BarResults) - -> Promise<(), Error> - { + fn bar( + &mut self, + _params: test_interface::BarParams, + _results: test_interface::BarResults, + ) -> Promise<(), Error> { self.increment_call_count(); Promise::err(Error::unimplemented("bar is not implemented".to_string())) } - fn baz(&mut self, - params: test_interface::BazParams, - _results: test_interface::BazResults) - -> Promise<(), Error> - { + fn baz( + &mut self, + params: test_interface::BazParams, + _results: test_interface::BazResults, + ) -> Promise<(), Error> { self.increment_call_count(); crate::test_util::CheckTestMessage::check_test_message(pry!(pry!(params.get()).get_s())); Promise::ok(()) @@ -166,11 +177,11 @@ impl test_interface::Server for TestInterface { struct TestExtends; impl test_interface::Server for TestExtends { - fn foo(&mut self, - params: test_interface::FooParams, - mut results: test_interface::FooResults) - -> Promise<(), Error> - { + fn foo( + &mut self, + params: test_interface::FooParams, + mut results: test_interface::FooResults, + ) -> Promise<(), Error> { let params = pry!(params.get()); if params.get_i() != 321 { return Promise::err(Error::failed(format!("expected i to equal 321"))); @@ -185,45 +196,45 @@ impl test_interface::Server for TestExtends { Promise::ok(()) } - fn bar(&mut self, - _params: test_interface::BarParams, - _results: test_interface::BarResults) - -> Promise<(), Error> - { + fn bar( + &mut self, + _params: test_interface::BarParams, + _results: test_interface::BarResults, + ) -> Promise<(), Error> { Promise::err(Error::unimplemented("bar is not implemented".to_string())) } - fn baz(&mut self, - _params: test_interface::BazParams, - _results: test_interface::BazResults) - -> Promise<(), Error> - { + fn baz( + &mut self, + _params: test_interface::BazParams, + _results: test_interface::BazResults, + ) -> Promise<(), Error> { Promise::err(Error::unimplemented("baz is not implemented".to_string())) } } impl test_extends::Server for TestExtends { - fn qux(&mut self, - _params: test_extends::QuxParams, - _results: test_extends::QuxResults) - -> Promise<(), Error> - { + fn qux( + &mut self, + _params: test_extends::QuxParams, + _results: test_extends::QuxResults, + ) -> Promise<(), Error> { Promise::err(Error::unimplemented("qux is not implemented".to_string())) } - fn corge(&mut self, - _params: test_extends::CorgeParams, - _results: test_extends::CorgeResults) - -> Promise<(), Error> - { + fn corge( + &mut self, + _params: test_extends::CorgeParams, + _results: test_extends::CorgeResults, + ) -> Promise<(), Error> { Promise::err(Error::unimplemented("corge is not implemented".to_string())) } - fn grault(&mut self, - _params: test_extends::GraultParams, - mut results: test_extends::GraultResults) - -> Promise<(), Error> - { + fn grault( + &mut self, + _params: test_extends::GraultParams, + mut results: test_extends::GraultResults, + ) -> Promise<(), Error> { crate::test_util::init_test_message(results.get()); Promise::ok(()) } @@ -232,11 +243,11 @@ impl test_extends::Server for TestExtends { struct TestPipeline; impl test_pipeline::Server for TestPipeline { - fn get_cap(&mut self, - params: test_pipeline::GetCapParams, - mut results: test_pipeline::GetCapResults) - -> Promise<(), Error> - { + fn get_cap( + &mut self, + params: test_pipeline::GetCapParams, + mut results: test_pipeline::GetCapResults, + ) -> Promise<(), Error> { if pry!(params.get()).get_n() != 234 { return Promise::err(Error::failed("expected n to equal 234".to_string())); } @@ -252,19 +263,21 @@ impl test_pipeline::Server for TestPipeline { results.get().set_s("bar"); // TODO implement better casting - results.get().init_out_box().set_cap( - test_interface::Client { + results + .get() + .init_out_box() + .set_cap(test_interface::Client { client: capnp_rpc::new_client::(TestExtends).client, }); Ok(()) })) } - fn get_null_cap(&mut self, - _params: test_pipeline::GetNullCapParams, - _results: test_pipeline::GetNullCapResults) - -> Promise<(), Error> - { + fn get_null_cap( + &mut self, + _params: test_pipeline::GetNullCapParams, + _results: test_pipeline::GetNullCapResults, + ) -> Promise<(), Error> { Promise::ok(()) } } @@ -280,11 +293,11 @@ impl TestCallOrder { } impl test_call_order::Server for TestCallOrder { - fn get_call_sequence(&mut self, - _params: test_call_order::GetCallSequenceParams, - mut results: test_call_order::GetCallSequenceResults) - -> Promise<(), Error> - { + fn get_call_sequence( + &mut self, + _params: test_call_order::GetCallSequenceParams, + mut results: test_call_order::GetCallSequenceResults, + ) -> Promise<(), Error> { results.get().set_n(self.count); self.count += 1; Promise::ok(()) @@ -305,7 +318,7 @@ impl TestMoreStuff { client_to_hold: None, } } -/* + /* pub fn get_call_count(&self) -> Rc> { self.call_count.clone() } @@ -315,11 +328,11 @@ impl TestMoreStuff { } impl test_call_order::Server for TestMoreStuff { - fn get_call_sequence(&mut self, - _params: test_call_order::GetCallSequenceParams, - mut results: test_call_order::GetCallSequenceResults) - -> Promise<(), Error> - { + fn get_call_sequence( + &mut self, + _params: test_call_order::GetCallSequenceParams, + mut results: test_call_order::GetCallSequenceResults, + ) -> Promise<(), Error> { results.get().set_n(self.call_count); self.call_count += 1; Promise::ok(()) @@ -327,11 +340,11 @@ impl test_call_order::Server for TestMoreStuff { } impl test_more_stuff::Server for TestMoreStuff { - fn call_foo(&mut self, - params: test_more_stuff::CallFooParams, - mut results: test_more_stuff::CallFooResults) - -> Promise<(), Error> - { + fn call_foo( + &mut self, + params: test_more_stuff::CallFooParams, + mut results: test_more_stuff::CallFooResults, + ) -> Promise<(), Error> { self.call_count += 1; let cap = pry!(pry!(params.get()).get_cap()); let mut request = cap.foo_request(); @@ -347,11 +360,11 @@ impl test_more_stuff::Server for TestMoreStuff { })) } - fn call_foo_when_resolved(&mut self, - params: test_more_stuff::CallFooWhenResolvedParams, - mut results: test_more_stuff::CallFooWhenResolvedResults) - -> Promise<(), Error> - { + fn call_foo_when_resolved( + &mut self, + params: test_more_stuff::CallFooWhenResolvedParams, + mut results: test_more_stuff::CallFooWhenResolvedResults, + ) -> Promise<(), Error> { self.call_count += 1; let cap = pry!(pry!(params.get()).get_cap()); Promise::from_future(cap.client.when_resolved().and_then(move |()| { @@ -368,11 +381,11 @@ impl test_more_stuff::Server for TestMoreStuff { })) } - fn never_return(&mut self, - params: test_more_stuff::NeverReturnParams, - mut results: test_more_stuff::NeverReturnResults) - -> Promise<(), Error> - { + fn never_return( + &mut self, + params: test_more_stuff::NeverReturnParams, + mut results: test_more_stuff::NeverReturnResults, + ) -> Promise<(), Error> { self.call_count += 1; let cap = pry!(pry!(params.get()).get_cap()); @@ -389,31 +402,31 @@ impl test_more_stuff::Server for TestMoreStuff { promise } - fn hold(&mut self, - params: test_more_stuff::HoldParams, - _results: test_more_stuff::HoldResults) - -> Promise<(), Error> - { + fn hold( + &mut self, + params: test_more_stuff::HoldParams, + _results: test_more_stuff::HoldResults, + ) -> Promise<(), Error> { self.call_count += 1; self.client_to_hold = Some(pry!(pry!(params.get()).get_cap())); Promise::ok(()) } - fn dont_hold(&mut self, - params: test_more_stuff::DontHoldParams, - _results: test_more_stuff::DontHoldResults) - -> Promise<(), Error> - { + fn dont_hold( + &mut self, + params: test_more_stuff::DontHoldParams, + _results: test_more_stuff::DontHoldResults, + ) -> Promise<(), Error> { self.call_count += 1; let _ = Some(pry!(pry!(params.get()).get_cap())); Promise::ok(()) } - fn call_held(&mut self, - _params: test_more_stuff::CallHeldParams, - mut results: test_more_stuff::CallHeldResults) - -> Promise<(), Error> - { + fn call_held( + &mut self, + _params: test_more_stuff::CallHeldParams, + mut results: test_more_stuff::CallHeldResults, + ) -> Promise<(), Error> { self.call_count += 1; match self.client_to_hold { None => Promise::err(Error::failed("no held client".to_string())), @@ -436,11 +449,11 @@ impl test_more_stuff::Server for TestMoreStuff { } } - fn get_held(&mut self, - _params: test_more_stuff::GetHeldParams, - mut results: test_more_stuff::GetHeldResults) - -> Promise<(), Error> - { + fn get_held( + &mut self, + _params: test_more_stuff::GetHeldParams, + mut results: test_more_stuff::GetHeldResults, + ) -> Promise<(), Error> { self.call_count += 1; match self.client_to_hold { None => Promise::err(Error::failed("no held client".to_string())), @@ -451,66 +464,66 @@ impl test_more_stuff::Server for TestMoreStuff { } } - fn echo(&mut self, - params: test_more_stuff::EchoParams, - mut results: test_more_stuff::EchoResults) - -> Promise<(), Error> - { + fn echo( + &mut self, + params: test_more_stuff::EchoParams, + mut results: test_more_stuff::EchoResults, + ) -> Promise<(), Error> { self.call_count += 1; results.get().set_cap(pry!(pry!(params.get()).get_cap())); Promise::ok(()) } - fn expect_cancel(&mut self, - _params: test_more_stuff::ExpectCancelParams, - _results: test_more_stuff::ExpectCancelResults) - -> Promise<(), Error> - { + fn expect_cancel( + &mut self, + _params: test_more_stuff::ExpectCancelParams, + _results: test_more_stuff::ExpectCancelResults, + ) -> Promise<(), Error> { unimplemented!() } - fn get_handle(&mut self, - _params: test_more_stuff::GetHandleParams, - mut results: test_more_stuff::GetHandleResults) - -> Promise<(), Error> - { + fn get_handle( + &mut self, + _params: test_more_stuff::GetHandleParams, + mut results: test_more_stuff::GetHandleResults, + ) -> Promise<(), Error> { self.call_count += 1; let handle = Handle::new(&self.handle_count); results.get().set_handle(capnp_rpc::new_client(handle)); Promise::ok(()) } - fn get_handle_count(&mut self, - _params: test_more_stuff::GetHandleCountParams, - mut results: test_more_stuff::GetHandleCountResults) - -> Promise<(), Error> - { + fn get_handle_count( + &mut self, + _params: test_more_stuff::GetHandleCountParams, + mut results: test_more_stuff::GetHandleCountResults, + ) -> Promise<(), Error> { self.call_count += 1; results.get().set_count(self.handle_count.get()); Promise::ok(()) } - fn get_null(&mut self, - _params: test_more_stuff::GetNullParams, - _results: test_more_stuff::GetNullResults) - -> Promise<(), Error> - { + fn get_null( + &mut self, + _params: test_more_stuff::GetNullParams, + _results: test_more_stuff::GetNullResults, + ) -> Promise<(), Error> { unimplemented!() } - fn method_with_defaults(&mut self, - _params: test_more_stuff::MethodWithDefaultsParams, - _results: test_more_stuff::MethodWithDefaultsResults) - -> Promise<(), Error> - { + fn method_with_defaults( + &mut self, + _params: test_more_stuff::MethodWithDefaultsParams, + _results: test_more_stuff::MethodWithDefaultsResults, + ) -> Promise<(), Error> { unimplemented!() } - fn call_each_capability(&mut self, - params: test_more_stuff::CallEachCapabilityParams, - _results: test_more_stuff::CallEachCapabilityResults) - -> Promise<(), Error> - { + fn call_each_capability( + &mut self, + params: test_more_stuff::CallEachCapabilityParams, + _results: test_more_stuff::CallEachCapabilityResults, + ) -> Promise<(), Error> { let mut results = Vec::new(); for cap in pry!(pry!(params.get()).get_caps()) { let mut request = pry!(cap).foo_request(); @@ -560,34 +573,36 @@ impl TestCapDestructor { impl Drop for TestCapDestructor { fn drop(&mut self) { match self.fulfiller.take() { - Some(f) => { let _ = f.send(()); } + Some(f) => { + let _ = f.send(()); + } None => (), } } } impl test_interface::Server for TestCapDestructor { - fn foo(&mut self, - params: test_interface::FooParams, - results: test_interface::FooResults) - -> Promise<(), Error> - { + fn foo( + &mut self, + params: test_interface::FooParams, + results: test_interface::FooResults, + ) -> Promise<(), Error> { self.imp.foo(params, results) } - fn bar(&mut self, - _params: test_interface::BarParams, - _results: test_interface::BarResults) - -> Promise<(), Error> - { + fn bar( + &mut self, + _params: test_interface::BarParams, + _results: test_interface::BarResults, + ) -> Promise<(), Error> { Promise::err(Error::unimplemented("bar is not implemented".to_string())) } - fn baz(&mut self, - _params: test_interface::BazParams, - _results: test_interface::BazResults) - -> Promise<(), Error> - { + fn baz( + &mut self, + _params: test_interface::BazParams, + _results: test_interface::BazResults, + ) -> Promise<(), Error> { Promise::err(Error::unimplemented("bar is not implemented".to_string())) } } @@ -595,53 +610,55 @@ impl test_interface::Server for TestCapDestructor { pub struct CssHandle {} impl CssHandle { - pub fn new() -> Self { Self {} } + pub fn new() -> Self { + Self {} + } } impl test_capability_server_set::handle::Server for CssHandle {} pub struct TestCapabilityServerSet { - set: Rc>>, + set: Rc< + RefCell< + capnp_rpc::CapabilityServerSet, + >, + >, } impl TestCapabilityServerSet { pub fn new() -> Self { Self { - set: Rc::new(RefCell::new(capnp_rpc::CapabilityServerSet::new())) + set: Rc::new(RefCell::new(capnp_rpc::CapabilityServerSet::new())), } } } impl test_capability_server_set::Server for TestCapabilityServerSet { - fn create_handle(&mut self, - _: test_capability_server_set::CreateHandleParams, - mut results: test_capability_server_set::CreateHandleResults) - -> Promise<(), Error> - { - results.get().set_handle(self.set.borrow_mut().new_client(CssHandle::new())); + fn create_handle( + &mut self, + _: test_capability_server_set::CreateHandleParams, + mut results: test_capability_server_set::CreateHandleResults, + ) -> Promise<(), Error> { + results + .get() + .set_handle(self.set.borrow_mut().new_client(CssHandle::new())); Promise::ok(()) } - fn check_handle(&mut self, - params: test_capability_server_set::CheckHandleParams, - mut results: test_capability_server_set::CheckHandleResults) - -> Promise<(), Error> - { + fn check_handle( + &mut self, + params: test_capability_server_set::CheckHandleParams, + mut results: test_capability_server_set::CheckHandleResults, + ) -> Promise<(), Error> { let set = self.set.clone(); let handle = pry!(pry!(params.get()).get_handle()); Promise::from_future(async move { let resolved = capnp::capability::get_resolved_cap(handle).await; match set.borrow().get_local_server_of_resolved(&resolved) { None => (), - Some(_) => { - results.get().set_is_ours(true) - } + Some(_) => results.get().set_is_ours(true), } Ok(()) }) } } - - diff --git a/capnp-rpc/test/test.rs b/capnp-rpc/test/test.rs index 6fa1f08df..38827d25b 100644 --- a/capnp-rpc/test/test.rs +++ b/capnp-rpc/test/test.rs @@ -21,67 +21,78 @@ #![cfg(test)] -use capnp::Error; use capnp::capability::{FromClientHook, Promise}; -use capnp_rpc::{RpcSystem, rpc_twoparty_capnp, twoparty}; +use capnp::Error; +use capnp_rpc::{rpc_twoparty_capnp, twoparty, RpcSystem}; -use futures::{Future, FutureExt, TryFutureExt}; use futures::channel::oneshot; +use futures::{Future, FutureExt, TryFutureExt}; pub mod test_capnp { - include!(concat!(env!("OUT_DIR"), "/test_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/test_capnp.rs")); } - pub mod impls; pub mod test_util; fn canceled_to_error(_e: futures::channel::oneshot::Canceled) -> Error { - Error::failed(format!("oneshot was canceled")) + Error::failed(format!("oneshot was canceled")) } #[test] fn drop_rpc_system() { let (writer, reader) = async_byte_channel::channel(); - let network = - Box::new(twoparty::VatNetwork::new(reader, writer, - rpc_twoparty_capnp::Side::Client, - Default::default())); + let network = Box::new(twoparty::VatNetwork::new( + reader, + writer, + rpc_twoparty_capnp::Side::Client, + Default::default(), + )); let rpc_system = RpcSystem::new(network, None); drop(rpc_system); } -fn disconnector_setup() -> ( RpcSystem, RpcSystem ) { +fn disconnector_setup() -> ( + RpcSystem, + RpcSystem, +) { let (client_writer, server_reader) = async_byte_channel::channel(); let (server_writer, client_reader) = async_byte_channel::channel(); - let client_network = - Box::new(twoparty::VatNetwork::new(client_reader, client_writer, - rpc_twoparty_capnp::Side::Client, - Default::default())); + let client_network = Box::new(twoparty::VatNetwork::new( + client_reader, + client_writer, + rpc_twoparty_capnp::Side::Client, + Default::default(), + )); let client_rpc_system = RpcSystem::new(client_network, None); - let server_network = - Box::new(twoparty::VatNetwork::new(server_reader, server_writer, - rpc_twoparty_capnp::Side::Server, - Default::default())); + let server_network = Box::new(twoparty::VatNetwork::new( + server_reader, + server_writer, + rpc_twoparty_capnp::Side::Server, + Default::default(), + )); let bootstrap: test_capnp::bootstrap::Client = capnp_rpc::new_client(impls::Bootstrap); let server_rpc_system = RpcSystem::new(server_network, Some(bootstrap.client)); - ( client_rpc_system, server_rpc_system ) + (client_rpc_system, server_rpc_system) } fn spawn(spawner: &mut futures::executor::LocalSpawner, task: F) - where F: Future> + 'static, +where + F: Future> + 'static, { - use futures::task::{LocalSpawnExt}; - spawner.spawn_local(task.map(|r| { - if let Err(e) = r { - panic!("Error on spawned task: {:?}", e); - } - })).unwrap(); + use futures::task::LocalSpawnExt; + spawner + .spawn_local(task.map(|r| { + if let Err(e) = r { + panic!("Error on spawned task: {:?}", e); + } + })) + .unwrap(); } #[test] @@ -90,16 +101,25 @@ fn drop_import_client_after_disconnect() { let mut spawner = pool.spawner(); let (mut client_rpc_system, server_rpc_system) = disconnector_setup(); - let client: test_capnp::bootstrap::Client = client_rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); + let client: test_capnp::bootstrap::Client = + client_rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); spawn(&mut spawner, client_rpc_system); let (tx, rx) = oneshot::channel::<()>(); let rx = rx.map_err(crate::canceled_to_error); - spawn(&mut spawner, futures::future::try_join(rx, server_rpc_system).map(|_|Ok(()))); + spawn( + &mut spawner, + futures::future::try_join(rx, server_rpc_system).map(|_| Ok(())), + ); pool.run_until(async move { - client.test_interface_request().send().promise.await.unwrap(); + client + .test_interface_request() + .send() + .promise + .await + .unwrap(); drop(tx); match client.test_interface_request().send().promise.await { @@ -124,19 +144,32 @@ fn disconnector_disconnects() { let mut spawner = pool.spawner(); let (mut client_rpc_system, server_rpc_system) = disconnector_setup(); - let client: test_capnp::bootstrap::Client = client_rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); - let disconnector: capnp_rpc::Disconnector = client_rpc_system.get_disconnector(); + let client: test_capnp::bootstrap::Client = + client_rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); + let disconnector: capnp_rpc::Disconnector = + client_rpc_system.get_disconnector(); spawn(&mut spawner, client_rpc_system); let (tx, rx) = oneshot::channel::<()>(); //send on tx when server_rpc_system exits - spawn(&mut spawner, server_rpc_system.map(|x| {let _ = tx.send(()).expect("sending on tx"); x})); + spawn( + &mut spawner, + server_rpc_system.map(|x| { + let _ = tx.send(()).expect("sending on tx"); + x + }), + ); pool.run_until(async move { //make sure we can make an RPC system call - client.test_interface_request().send().promise.await.unwrap(); + client + .test_interface_request() + .send() + .promise + .await + .unwrap(); //disconnect from the server; comment this next line out to see the test fail disconnector.await.unwrap(); @@ -152,9 +185,10 @@ fn disconnector_disconnects() { } fn rpc_top_level(main: F) - where F: FnOnce(futures::executor::LocalSpawner, test_capnp::bootstrap::Client) -> G, - F: Send + 'static, - G: Future> + 'static +where + F: FnOnce(futures::executor::LocalSpawner, test_capnp::bootstrap::Client) -> G, + F: Send + 'static, + G: Future> + 'static, { let mut pool = futures::executor::LocalPool::new(); let mut spawner = pool.spawner(); @@ -162,23 +196,28 @@ fn rpc_top_level(main: F) let (server_writer, client_reader) = async_byte_channel::channel(); let join_handle = std::thread::spawn(move || { - let network = - Box::new(twoparty::VatNetwork::new(server_reader, server_writer, - rpc_twoparty_capnp::Side::Server, - Default::default())); + let network = Box::new(twoparty::VatNetwork::new( + server_reader, + server_writer, + rpc_twoparty_capnp::Side::Server, + Default::default(), + )); let bootstrap: test_capnp::bootstrap::Client = capnp_rpc::new_client(impls::Bootstrap); let rpc_system = RpcSystem::new(network, Some(bootstrap.client)); futures::executor::block_on(rpc_system).unwrap(); }); - let network = - Box::new(twoparty::VatNetwork::new(client_reader, client_writer, - rpc_twoparty_capnp::Side::Client, - Default::default())); + let network = Box::new(twoparty::VatNetwork::new( + client_reader, + client_writer, + rpc_twoparty_capnp::Side::Client, + Default::default(), + )); let mut rpc_system = RpcSystem::new(network, None); - let client: test_capnp::bootstrap::Client = rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); + let client: test_capnp::bootstrap::Client = + rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server); let disconnector = rpc_system.get_disconnector(); spawn(&mut spawner, rpc_system); @@ -193,9 +232,7 @@ fn rpc_top_level(main: F) #[test] fn do_nothing() { - rpc_top_level(|_spawner, _client| async { - Ok(()) - }); + rpc_top_level(|_spawner, _client| async { Ok(()) }); } #[test] @@ -213,12 +250,8 @@ fn basic_rpc_calls() { let promise3 = request3.send().promise.then(|result| { // We expect this call to fail. match result { - Ok(_) => { - Promise::err(Error::failed("expected bar() to fail".to_string())) - } - Err(_) => { - Promise::ok(()) - } + Ok(_) => Promise::err(Error::failed("expected bar() to fail".to_string())), + Err(_) => Promise::ok(()), } }); @@ -258,8 +291,9 @@ fn basic_pipelining() { let pipeline_promise = pipeline_request.send(); let pipeline_request2 = { - let extends_client = - crate::test_capnp::test_extends::Client { client: promise.pipeline.get_out_box().get_cap().client }; + let extends_client = crate::test_capnp::test_extends::Client { + client: promise.pipeline.get_out_box().get_cap().client, + }; extends_client.grault_request() }; let pipeline_promise2 = pipeline_request2.send(); @@ -267,7 +301,9 @@ fn basic_pipelining() { drop(promise); // Just to be annoying, drop the original promise. if chained_call_count.get() != 0 { - return Err(Error::failed("expected chained_call_count to equal 0".to_string())); + return Err(Error::failed( + "expected chained_call_count to equal 0".to_string(), + )); } let response = pipeline_promise.promise.await?; @@ -293,15 +329,20 @@ fn pipelining_return_null() { let cap = request.send().pipeline.get_cap(); match cap.foo_request().send().promise.await { Err(ref e) => { - if e.description.contains("Message contains null capability pointer") { + if e.description + .contains("Message contains null capability pointer") + { Ok(()) } else { - Err(Error::failed(format!("Should have gotten null capability error. Instead got {:?}", e))) + Err(Error::failed(format!( + "Should have gotten null capability error. Instead got {:?}", + e + ))) } } - Ok(_) => { - Err(Error::failed(format!("Should have gotten null capability error."))) - } + Ok(_) => Err(Error::failed(format!( + "Should have gotten null capability error." + ))), } }); } @@ -324,33 +365,42 @@ fn release_simple() { let client = response.get()?.get_cap()?; let handle1 = client.get_handle_request().send().promise; - let ::capnp::capability::RemotePromise {promise, pipeline} = client.get_handle_request().send(); + let ::capnp::capability::RemotePromise { promise, pipeline } = + client.get_handle_request().send(); let handle2 = promise.await?.get()?.get_handle()?; let get_count_response = client.get_handle_count_request().send().promise.await?; if get_count_response.get()?.get_count() != 2 { - return Err(Error::failed("expected handle count to equal 2".to_string())) + return Err(Error::failed( + "expected handle count to equal 2".to_string(), + )); } drop(handle1); let get_count_response = client.get_handle_count_request().send().promise.await?; if get_count_response.get()?.get_count() != 1 { - return Err(Error::failed("expected handle count to equal 1".to_string())) + return Err(Error::failed( + "expected handle count to equal 1".to_string(), + )); } drop(handle2); let get_count_response = client.get_handle_count_request().send().promise.await?; if get_count_response.get()?.get_count() != 1 { - return Err(Error::failed("expected handle count to equal 1".to_string())) + return Err(Error::failed( + "expected handle count to equal 1".to_string(), + )); } drop(pipeline); let get_count_response = client.get_handle_count_request().send().promise.await?; if get_count_response.get()?.get_count() != 0 { - return Err(Error::failed("expected handle count to equal 0".to_string())) + return Err(Error::failed( + "expected handle count to equal 0".to_string(), + )); } Ok(()) @@ -411,12 +461,15 @@ fn promise_resolve() { // Make sure getCap() has been called on the server side by sending another call and waiting // for it. - let client2 = crate::test_capnp::test_call_order::Client { client: client.clone().client }; + let client2 = crate::test_capnp::test_call_order::Client { + client: client.clone().client, + }; let _response = client2.get_call_sequence_request().send().promise.await?; let server = impls::TestInterface::new(); let _ = paf_fulfiller.send( - capnp_rpc::new_client::(server).client); + capnp_rpc::new_client::(server).client, + ); let response = promise.await?; if response.get()?.get_s()? != "bar" { @@ -442,12 +495,15 @@ fn retain_and_release() { let (destroyed_done_sender, destroyed_done_receiver) = oneshot::channel::<()>(); let destroyed1 = destroyed.clone(); - spawn(&mut spawner, promise.map_err(canceled_to_error).map(move |r| { - r?; - destroyed1.set(true); - let _ = destroyed_done_sender.send(()); - Ok(()) - })); + spawn( + &mut spawner, + promise.map_err(canceled_to_error).map(move |r| { + r?; + destroyed1.set(true); + let _ = destroyed_done_sender.send(()); + Ok(()) + }), + ); { let response = client.test_more_stuff_request().send().promise.await?; @@ -455,25 +511,29 @@ fn retain_and_release() { { let mut request = client.hold_request(); - request.get().set_cap(capnp_rpc::new_client(impls::TestCapDestructor::new(fulfiller))); + request + .get() + .set_cap(capnp_rpc::new_client(impls::TestCapDestructor::new( + fulfiller, + ))); request.send().promise.await?; } - let client1 : crate::test_capnp::test_call_order::Client = client.clone().cast_to(); + let client1: crate::test_capnp::test_call_order::Client = client.clone().cast_to(); let response = client1.get_call_sequence_request().send().promise.await?; if response.get()?.get_n() != 1 { - return Err(Error::failed("N should equal 1".to_string())) + return Err(Error::failed("N should equal 1".to_string())); } if destroyed.get() { - return Err(Error::failed("shouldn't be destroyed yet".to_string())) + return Err(Error::failed("shouldn't be destroyed yet".to_string())); } // We can ask it to call the held capability. let response = client.call_held_request().send().promise.await?; if response.get()?.get_s()? != "bar" { - return Err(Error::failed("S should equal 'bar'".to_string())) + return Err(Error::failed("S should equal 'bar'".to_string())); } { @@ -519,7 +579,7 @@ fn retain_and_release() { } if destroyed.get() { - return Err(Error::failed("haven't released it yet".to_string())) + return Err(Error::failed("haven't released it yet".to_string())); } } @@ -534,8 +594,8 @@ fn retain_and_release() { #[test] fn cancel_releases_params() { - use std::rc::Rc; use std::cell::Cell; + use std::rc::Rc; rpc_top_level(|mut spawner, client| async move { let response = client.test_more_stuff_request().send().promise.await?; @@ -547,23 +607,30 @@ fn cancel_releases_params() { let (destroyed_done_sender, destroyed_done_receiver) = oneshot::channel::<()>(); let destroyed1 = destroyed.clone(); - spawn(&mut spawner, promise.map_err(canceled_to_error).map(move |r| { - r?; - destroyed1.set(true); - let _ = destroyed_done_sender.send(()); - Ok(()) - })); + spawn( + &mut spawner, + promise.map_err(canceled_to_error).map(move |r| { + r?; + destroyed1.set(true); + let _ = destroyed_done_sender.send(()); + Ok(()) + }), + ); { let mut request = client.never_return_request(); - request.get().set_cap(capnp_rpc::new_client(impls::TestCapDestructor::new(fulfiller))); + request + .get() + .set_cap(capnp_rpc::new_client(impls::TestCapDestructor::new( + fulfiller, + ))); { let _response_promise = request.send(); // Allow some time to settle. - let client : crate::test_capnp::test_call_order::Client = client.cast_to(); + let client: crate::test_capnp::test_call_order::Client = client.cast_to(); let response = client.get_call_sequence_request().send().promise.await?; if response.get()?.get_n() != 1 { return Err(Error::failed("N should equal 1.".to_string())); @@ -600,26 +667,32 @@ fn dont_hold() { let mut request = client.dont_hold_request(); request.get().set_cap(cap.clone()); - request.send().promise.and_then(move |_response| { - let mut request = client.dont_hold_request(); - request.get().set_cap(cap.clone()); - request.send().promise.and_then(move |_| { - drop(fulfiller); - Promise::ok(()) + request + .send() + .promise + .and_then(move |_response| { + let mut request = client.dont_hold_request(); + request.get().set_cap(cap.clone()); + request.send().promise.and_then(move |_| { + drop(fulfiller); + Promise::ok(()) + }) }) - }).await + .await }); } -fn get_call_sequence(client: &crate::test_capnp::test_call_order::Client, expected: u32) - -> ::capnp::capability::RemotePromise -{ +fn get_call_sequence( + client: &crate::test_capnp::test_call_order::Client, + expected: u32, +) -> ::capnp::capability::RemotePromise< + crate::test_capnp::test_call_order::get_call_sequence_results::Owned, +> { let mut req = client.get_call_sequence_request(); req.get().set_expected(expected); req.send() } - #[test] fn embargo_success() { rpc_top_level(|_spawner, client| async move { @@ -628,7 +701,7 @@ fn embargo_success() { let server = crate::impls::TestCallOrder::new(); - let client2 : crate::test_capnp::test_call_order::Client = client.clone().cast_to(); + let client2: crate::test_capnp::test_call_order::Client = client.clone().cast_to(); let early_call = client2.get_call_sequence_request().send(); drop(client2); @@ -651,29 +724,29 @@ fn embargo_success() { let call4 = get_call_sequence(&pipeline, 4); let call5 = get_call_sequence(&pipeline, 5); - futures::future::try_join_all( - vec![call0.promise, - call1.promise, - call2.promise, - call3.promise, - call4.promise, - call5.promise - ]).map(|responses| { - let mut counter = 0; - for r in responses?.into_iter() { - if counter != r.get()?.get_n() { - return Err(Error::failed( - "calls arrived out of order".to_string())) - } - counter += 1; + futures::future::try_join_all(vec![ + call0.promise, + call1.promise, + call2.promise, + call3.promise, + call4.promise, + call5.promise, + ]) + .map(|responses| { + let mut counter = 0; + for r in responses?.into_iter() { + if counter != r.get()?.get_n() { + return Err(Error::failed("calls arrived out of order".to_string())); } - Ok(()) - }).await + counter += 1; + } + Ok(()) + }) + .await }); } -async fn expect_promise_throws(promise: Promise) - -> Result<(), Error> { +async fn expect_promise_throws(promise: Promise) -> Result<(), Error> { let r = promise.await; match r { Ok(_) => Err(Error::failed("expected promise to fail".to_string())), @@ -691,7 +764,7 @@ fn embargo_error() { let cap: crate::test_capnp::test_call_order::Client = ::capnp_rpc::new_promise_client(promise.map_err(canceled_to_error)); - let client2 : crate::test_capnp::test_call_order::Client = client.clone().cast_to(); + let client2: crate::test_capnp::test_call_order::Client = client.clone().cast_to(); let early_call = client2.get_call_sequence_request().send(); drop(client2); @@ -736,7 +809,7 @@ fn echo_destruction() { let cap: crate::test_capnp::test_call_order::Client = ::capnp_rpc::new_promise_client(promise.map_err(canceled_to_error)); - let client2 : crate::test_capnp::test_call_order::Client = client.clone().cast_to(); + let client2: crate::test_capnp::test_call_order::Client = client.clone().cast_to(); let early_call = client2.get_call_sequence_request().send(); drop(client2); @@ -746,13 +819,16 @@ fn echo_destruction() { let pipeline = echo.pipeline.get_cap(); - early_call.promise.and_then(move |_early_call_response| { - let _ = get_call_sequence(&pipeline, 2); - echo.promise.and_then(move |_echo_response| { - drop(fulfiller); - Promise::ok(()) + early_call + .promise + .and_then(move |_early_call_response| { + let _ = get_call_sequence(&pipeline, 2); + echo.promise.and_then(move |_echo_response| { + drop(fulfiller); + Promise::ok(()) + }) }) - }).await + .await }) } @@ -791,7 +867,8 @@ fn local_client_send_cap() { fn local_client_return_cap() { let server = crate::impls::Bootstrap; let client: crate::test_capnp::bootstrap::Client = capnp_rpc::new_client(server); - let response = futures::executor::block_on(client.test_interface_request().send().promise).unwrap(); + let response = + futures::executor::block_on(client.test_interface_request().send().promise).unwrap(); let client1 = response.get().unwrap().get_cap().unwrap(); let mut request = client1.foo_request(); @@ -832,12 +909,12 @@ fn capability_list() { #[test] fn capability_server_set() { - use capnp_rpc::CapabilityServerSet; - use crate::test_capnp::test_interface; use crate::impls; - let mut set1 : CapabilityServerSet = + use crate::test_capnp::test_interface; + use capnp_rpc::CapabilityServerSet; + let mut set1: CapabilityServerSet = CapabilityServerSet::new(); - let mut set2 : CapabilityServerSet = + let mut set2: CapabilityServerSet = CapabilityServerSet::new(); let client_standalone = capnp_rpc::new_client(impls::TestInterface::new()); @@ -852,10 +929,16 @@ fn capability_server_set() { // Getting the local server using the correct set works. let own_server1_again = futures::executor::block_on(set1.get_local_server(&client1)).unwrap(); - assert_eq!(own_server1_again.borrow().get_call_count().as_ptr(), own_server1_counter.as_ptr()); + assert_eq!( + own_server1_again.borrow().get_call_count().as_ptr(), + own_server1_counter.as_ptr() + ); let own_server2_again = futures::executor::block_on(set2.get_local_server(&client2)).unwrap(); - assert_eq!(own_server2_again.borrow().get_call_count().as_ptr(), own_server2_counter.as_ptr()); + assert_eq!( + own_server2_again.borrow().get_call_count().as_ptr(), + own_server2_counter.as_ptr() + ); // Getting the local server using the wrong set doesn't work. assert!(futures::executor::block_on(set1.get_local_server(&client2)).is_none()); @@ -877,7 +960,10 @@ fn capability_server_set() { assert!(fulfiller.send(client1.client).is_ok()); let own_server1_again2 = futures::executor::block_on(set1.get_local_server(&client_promise)).unwrap(); - assert_eq!(own_server1_again2.borrow().get_call_count().as_ptr(), own_server1_counter.as_ptr()); + assert_eq!( + own_server1_again2.borrow().get_call_count().as_ptr(), + own_server1_counter.as_ptr() + ); // Wrong set; returns None. assert!(futures::executor::block_on(set2.get_local_server(&client_promise2)).is_none()); @@ -889,10 +975,18 @@ fn capability_server_set() { #[test] fn capability_server_set_rpc() { rpc_top_level(|_spawner, client| async move { - let response1 = client.test_capability_server_set_request().send().promise.await?; + let response1 = client + .test_capability_server_set_request() + .send() + .promise + .await?; let client1 = response1.get()?.get_cap()?; - let response2 = client.test_capability_server_set_request().send().promise.await?; + let response2 = client + .test_capability_server_set_request() + .send() + .promise + .await?; let client2 = response2.get()?.get_cap()?; let handle1 = client1.create_handle_request().send().pipeline.get_handle(); diff --git a/capnp-rpc/test/test_util.rs b/capnp-rpc/test/test_util.rs index 911ec011b..eaeb3f883 100644 --- a/capnp-rpc/test/test_util.rs +++ b/capnp-rpc/test/test_util.rs @@ -19,7 +19,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - use crate::test_capnp::{test_all_types, TestEnum}; pub fn init_test_message(mut builder: test_all_types::Builder) { @@ -56,7 +55,9 @@ pub fn init_test_message(mut builder: test_all_types::Builder) { { let mut sub_sub_builder = sub_builder.reborrow().init_struct_field(); sub_sub_builder.set_text_field("nested"); - sub_sub_builder.init_struct_field().set_text_field("really nested"); + sub_sub_builder + .init_struct_field() + .set_text_field("really nested"); } sub_builder.set_enum_field(TestEnum::Baz); @@ -101,9 +102,18 @@ pub fn init_test_message(mut builder: test_all_types::Builder) { // ... { let mut struct_list = sub_builder.reborrow().init_struct_list(3); - struct_list.reborrow().get(0).set_text_field("x structlist 1"); - struct_list.reborrow().get(1).set_text_field("x structlist 2"); - struct_list.reborrow().get(2).set_text_field("x structlist 3"); + struct_list + .reborrow() + .get(0) + .set_text_field("x structlist 1"); + struct_list + .reborrow() + .get(1) + .set_text_field("x structlist 2"); + struct_list + .reborrow() + .get(2) + .set_text_field("x structlist 3"); } let mut enum_list = sub_builder.reborrow().init_enum_list(3); diff --git a/capnp/src/any_pointer.rs b/capnp/src/any_pointer.rs index 5f0e5c4b8..17a674339 100644 --- a/capnp/src/any_pointer.rs +++ b/capnp/src/any_pointer.rs @@ -26,8 +26,8 @@ use alloc::vec::Vec; use crate::capability::FromClientHook; use crate::private::capability::{ClientHook, PipelineHook, PipelineOp}; -use crate::private::layout::{PointerReader, PointerBuilder}; -use crate::traits::{FromPointerReader, FromPointerBuilder, SetPointerBuilder}; +use crate::private::layout::{PointerBuilder, PointerReader}; +use crate::traits::{FromPointerBuilder, FromPointerReader, SetPointerBuilder}; use crate::Result; #[derive(Copy, Clone)] @@ -44,10 +44,10 @@ impl crate::traits::Pipelined for Owned { #[derive(Copy, Clone)] pub struct Reader<'a> { - reader: PointerReader<'a> + reader: PointerReader<'a>, } -impl <'a> Reader<'a> { +impl<'a> Reader<'a> { pub fn new(reader: PointerReader<'_>) -> Reader<'_> { Reader { reader } } @@ -78,7 +78,7 @@ impl <'a> Reader<'a> { for op in ops { match *op { - PipelineOp::Noop => { } + PipelineOp::Noop => {} PipelineOp::GetPointerField(idx) => { pointer = pointer.get_struct(None)?.get_pointer_field(idx as usize); } @@ -89,8 +89,11 @@ impl <'a> Reader<'a> { } } -impl <'a> FromPointerReader<'a> for Reader<'a> { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { +impl<'a> FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { if default.is_some() { panic!("Unsupported: any_pointer with a default value."); } @@ -98,31 +101,36 @@ impl <'a> FromPointerReader<'a> for Reader<'a> { } } -impl <'a> crate::traits::SetPointerBuilder for Reader<'a> { - fn set_pointer_builder<'b>(mut pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a>, - canonicalize: bool) -> Result<()> { +impl<'a> crate::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder<'b>( + mut pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a>, + canonicalize: bool, + ) -> Result<()> { pointer.copy_from(value.reader, canonicalize) } } -impl <'a> crate::traits::Imbue<'a> for Reader<'a> { +impl<'a> crate::traits::Imbue<'a> for Reader<'a> { fn imbue(&mut self, cap_table: &'a crate::private::layout::CapTable) { - self.reader.imbue(crate::private::layout::CapTableReader::Plain(cap_table)); + self.reader + .imbue(crate::private::layout::CapTableReader::Plain(cap_table)); } } pub struct Builder<'a> { - builder: PointerBuilder<'a> + builder: PointerBuilder<'a>, } -impl <'a> Builder<'a> { +impl<'a> Builder<'a> { pub fn new(builder: PointerBuilder<'a>) -> Builder<'a> { Builder { builder } } pub fn reborrow(&mut self) -> Builder<'_> { - Builder { builder: self.builder.reborrow() } + Builder { + builder: self.builder.reborrow(), + } } pub fn is_null(&self) -> bool { @@ -134,11 +142,11 @@ impl <'a> Builder<'a> { self.builder.into_reader().total_size() } - pub fn get_as>(self) -> Result { + pub fn get_as>(self) -> Result { FromPointerBuilder::get_from_pointer(self.builder, None) } - pub fn init_as>(self) -> T { + pub fn init_as>(self) -> T { FromPointerBuilder::init_pointer(self.builder, 0) } @@ -161,18 +169,23 @@ impl <'a> Builder<'a> { } pub fn into_reader(self) -> Reader<'a> { - Reader { reader: self.builder.into_reader() } + Reader { + reader: self.builder.into_reader(), + } } } -impl <'a> FromPointerBuilder<'a> for Builder<'a> { +impl<'a> FromPointerBuilder<'a> for Builder<'a> { fn init_pointer(mut builder: PointerBuilder<'a>, _len: u32) -> Builder<'a> { if !builder.is_null() { builder.clear(); } Builder { builder } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { if default.is_some() { panic!("AnyPointer defaults are unsupported") } @@ -180,9 +193,10 @@ impl <'a> FromPointerBuilder<'a> for Builder<'a> { } } -impl <'a> crate::traits::ImbueMut<'a> for Builder<'a> { +impl<'a> crate::traits::ImbueMut<'a> for Builder<'a> { fn imbue_mut(&mut self, cap_table: &'a mut crate::private::layout::CapTable) { - self.builder.imbue(crate::private::layout::CapTableBuilder::Plain(cap_table)); + self.builder + .imbue(crate::private::layout::CapTableBuilder::Plain(cap_table)); } } @@ -195,11 +209,17 @@ pub struct Pipeline { impl Pipeline { pub fn new(hook: Box) -> Pipeline { - Pipeline { hook, ops: Vec::new() } + Pipeline { + hook, + ops: Vec::new(), + } } pub fn noop(&self) -> Pipeline { - Pipeline { hook: self.hook.add_ref(), ops: self.ops.clone() } + Pipeline { + hook: self.hook.add_ref(), + ops: self.ops.clone(), + } } pub fn get_pointer_field(&self, pointer_index: u16) -> Pipeline { @@ -208,7 +228,10 @@ impl Pipeline { new_ops.push(*op) } new_ops.push(PipelineOp::GetPointerField(pointer_index)); - Pipeline { hook : self.hook.add_ref(), ops: new_ops } + Pipeline { + hook: self.hook.add_ref(), + ops: new_ops, + } } pub fn as_cap(&self) -> Box { diff --git a/capnp/src/any_pointer_list.rs b/capnp/src/any_pointer_list.rs index e4d6d83e7..b9ecdd811 100644 --- a/capnp/src/any_pointer_list.rs +++ b/capnp/src/any_pointer_list.rs @@ -23,8 +23,8 @@ //! Note: this cannot be used for a list of structs, since such lists are not encoded //! as pointer lists. -use crate::traits::{FromPointerReader, FromPointerBuilder, ListIter, IndexMove}; -use crate::private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, Pointer}; +use crate::private::layout::{ListBuilder, ListReader, Pointer, PointerBuilder, PointerReader}; +use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter}; use crate::Result; #[derive(Clone, Copy)] @@ -37,114 +37,136 @@ impl crate::traits::Owned for Owned { #[derive(Clone, Copy)] pub struct Reader<'a> { - pub reader: ListReader<'a> + pub reader: ListReader<'a>, } -impl <'a> Reader<'a> { +impl<'a> Reader<'a> { pub(crate) fn new(reader: ListReader<'_>) -> Reader<'_> { Reader { reader } } - pub fn len(&self) -> u32 { self.reader.len() } + pub fn len(&self) -> u32 { + self.reader.len() + } - pub fn iter(self) -> ListIter, Result>>{ + pub fn iter(self) -> ListIter, Result>> { let l = self.len(); ListIter::new(self, l) } /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. - pub fn get(self, index : u32) -> crate::any_pointer::Reader<'a> { - assert!(index < self.len()); + pub fn get(self, index: u32) -> crate::any_pointer::Reader<'a> { + assert!(index < self.len()); crate::any_pointer::Reader::new(self.reader.get_pointer_element(index)) } /// Gets the element at position `index`. Returns `None` if `index` /// is greater than or equal to `len()`. - pub fn try_get(self, index : u32) -> Option> { - if index < self.len() { - Some(crate::any_pointer::Reader::new(self.reader.get_pointer_element(index))) + pub fn try_get(self, index: u32) -> Option> { + if index < self.len() { + Some(crate::any_pointer::Reader::new( + self.reader.get_pointer_element(index), + )) } else { None } } } -impl <'a> IndexMove>> for Reader<'a>{ +impl<'a> IndexMove>> for Reader<'a> { fn index_move(&self, index: u32) -> Result> { Ok(self.get(index)) } } -impl <'a> FromPointerReader<'a> for Reader<'a> { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader: reader.get_list(Pointer, default)? }) +impl<'a> FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(Pointer, default)?, + }) } } -impl <'a> crate::traits::IntoInternalListReader<'a> for Reader<'a> { +impl<'a> crate::traits::IntoInternalListReader<'a> for Reader<'a> { fn into_internal_list_reader(self) -> ListReader<'a> { self.reader } } pub struct Builder<'a> { - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a> Builder<'a> { - pub fn len(&self) -> u32 { self.builder.len() } +impl<'a> Builder<'a> { + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn into_reader(self) -> Reader<'a> { - Reader { reader: self.builder.into_reader() } + Reader { + reader: self.builder.into_reader(), + } } /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. - pub fn get(self, index : u32) -> crate::any_pointer::Builder<'a> { - assert!(index < self.len()); + pub fn get(self, index: u32) -> crate::any_pointer::Builder<'a> { + assert!(index < self.len()); crate::any_pointer::Builder::new(self.builder.get_pointer_element(index)) } /// Gets the element at position `index`. Returns `None` if `index` /// is greater than or equal to `len()`. - pub fn try_get(self, index : u32) -> Option> { - if index < self.len() { - Some(crate::any_pointer::Builder::new(self.builder.get_pointer_element(index))) + pub fn try_get(self, index: u32) -> Option> { + if index < self.len() { + Some(crate::any_pointer::Builder::new( + self.builder.get_pointer_element(index), + )) } else { None } } pub fn reborrow(&mut self) -> Builder<'_> { - Builder {builder: self.builder.reborrow()} + Builder { + builder: self.builder.reborrow(), + } } } -impl <'a> FromPointerBuilder<'a> for Builder<'a> { - fn init_pointer(builder: PointerBuilder<'a>, size : u32) -> Builder<'a> { +impl<'a> FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a> { Builder { - builder: builder.init_list(Pointer, size) + builder: builder.init_list(Pointer, size), } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { Ok(Builder { - builder: builder.get_list(Pointer, default)? + builder: builder.get_list(Pointer, default)?, }) } } -impl <'a> crate::traits::SetPointerBuilder for Reader<'a> { - fn set_pointer_builder<'b>(pointer: PointerBuilder<'b>, - value: Reader<'a>, - canonicalize: bool) -> Result<()> { +impl<'a> crate::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder<'b>( + pointer: PointerBuilder<'b>, + value: Reader<'a>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize)?; Ok(()) } } -impl <'a> core::iter::IntoIterator for Reader<'a> { +impl<'a> core::iter::IntoIterator for Reader<'a> { type Item = Result>; type IntoIter = ListIter, Self::Item>; diff --git a/capnp/src/capability.rs b/capnp/src/capability.rs index 31bda065f..9ad5a0b57 100644 --- a/capnp/src/capability.rs +++ b/capnp/src/capability.rs @@ -24,16 +24,16 @@ //! Roughly corresponds to capability.h in the C++ implementation. use alloc::boxed::Box; -use core::future::{Future}; -use core::pin::{Pin}; +use core::future::Future; use core::marker::{PhantomData, Unpin}; -use core::task::Poll; #[cfg(feature = "rpc_try")] use core::ops::Try; +use core::pin::Pin; +use core::task::Poll; -use crate::{any_pointer, Error, MessageSize}; -use crate::traits::{Pipelined, Owned}; use crate::private::capability::{ClientHook, ParamsHook, RequestHook, ResponseHook, ResultsHook}; +use crate::traits::{Owned, Pipelined}; +use crate::{any_pointer, Error, MessageSize}; /// A computation that might eventually resolve to a value of type `T` or to an error /// of type `E`. Dropping the promise cancels the computation. @@ -43,33 +43,39 @@ pub struct Promise { } enum PromiseInner { - Immediate(Result), - Deferred(Pin> + 'static>>), + Immediate(Result), + Deferred(Pin> + 'static>>), Empty, } // Allow Promise to be Unpin, regardless of whether T and E are. -impl Unpin for PromiseInner {} +impl Unpin for PromiseInner {} -impl Promise { +impl Promise { pub fn ok(value: T) -> Promise { - Promise { inner: PromiseInner::Immediate(Ok(value)) } + Promise { + inner: PromiseInner::Immediate(Ok(value)), + } } pub fn err(error: E) -> Promise { - Promise { inner: PromiseInner::Immediate(Err(error)) } + Promise { + inner: PromiseInner::Immediate(Err(error)), + } } pub fn from_future(f: F) -> Promise - where F: Future> + 'static + where + F: Future> + 'static, { - Promise { inner: PromiseInner::Deferred(Box::pin(f)) } + Promise { + inner: PromiseInner::Deferred(Box::pin(f)), + } } } -impl Future for Promise -{ - type Output = core::result::Result; +impl Future for Promise { + type Output = core::result::Result; fn poll(self: Pin<&mut Self>, cx: &mut ::core::task::Context) -> Poll { match self.get_mut().inner { @@ -111,7 +117,10 @@ impl std::ops::FromResidual for Promise { /// A promise for a result from a method call. #[must_use] -pub struct RemotePromise where Results: Pipelined + Owned + 'static { +pub struct RemotePromise +where + Results: Pipelined + Owned + 'static, +{ pub promise: Promise, crate::Error>, pub pipeline: Results::Pipeline, } @@ -122,11 +131,15 @@ pub struct Response { pub hook: Box, } -impl Response - where Results: Pipelined + Owned +impl Response +where + Results: Pipelined + Owned, { pub fn new(hook: Box) -> Response { - Response { marker: PhantomData, hook } + Response { + marker: PhantomData, + hook, + } } pub fn get(&self) -> crate::Result> { self.hook.get()?.get_as() @@ -136,14 +149,18 @@ impl Response /// A method call that has not been sent yet. pub struct Request { pub marker: PhantomData<(Params, Results)>, - pub hook: Box + pub hook: Box, } -impl Request - where Params: Owned +impl Request +where + Params: Owned, { - pub fn new(hook: Box) -> Request { - Request { hook, marker: PhantomData } + pub fn new(hook: Box) -> Request { + Request { + hook, + marker: PhantomData, + } } pub fn get(&mut self) -> Params::Builder<'_> { @@ -155,20 +172,25 @@ impl Request } } -impl Request -where Results: Pipelined + Owned + 'static + Unpin, - ::Pipeline: FromTypelessPipeline +impl Request +where + Results: Pipelined + Owned + 'static + Unpin, + ::Pipeline: FromTypelessPipeline, { pub fn send(self) -> RemotePromise { - let RemotePromise {promise, pipeline, ..} = self.hook.send(); - let typed_promise = Promise::from_future( - async move { - Ok(Response {hook: promise.await?.hook, - marker: PhantomData}) - }); - RemotePromise { promise: typed_promise, - pipeline: FromTypelessPipeline::new(pipeline) - } + let RemotePromise { + promise, pipeline, .. + } = self.hook.send(); + let typed_promise = Promise::from_future(async move { + Ok(Response { + hook: promise.await?.hook, + marker: PhantomData, + }) + }); + RemotePromise { + promise: typed_promise, + pipeline: FromTypelessPipeline::new(pipeline), + } } } @@ -178,12 +200,16 @@ pub struct Params { pub hook: Box, } -impl Params { +impl Params { pub fn new(hook: Box) -> Params { - Params { marker: PhantomData, hook } + Params { + marker: PhantomData, + hook, + } } pub fn get(&self) -> crate::Result> - where T: Owned + where + T: Owned, { self.hook.get()?.get_as() } @@ -195,25 +221,28 @@ pub struct Results { pub hook: Box, } -impl Results - where T: Owned +impl Results +where + T: Owned, { pub fn new(hook: Box) -> Results { - Results { marker: PhantomData, hook } + Results { + marker: PhantomData, + hook, + } } pub fn get(&mut self) -> T::Builder<'_> { self.hook.get().unwrap().get_as().unwrap() } - pub fn set(&mut self, other: T::Reader<'_>) -> crate::Result<()> - { + pub fn set(&mut self, other: T::Reader<'_>) -> crate::Result<()> { self.hook.get().unwrap().set_as(other) } } pub trait FromTypelessPipeline { - fn new (typeless: any_pointer::Pipeline) -> Self; + fn new(typeless: any_pointer::Pipeline) -> Self; } /// Trait implemented (via codegen) by all user-defined capability client types. @@ -230,14 +259,17 @@ pub trait FromClientHook { /// Casts `self` to another instance of `FromClientHook`. This always succeeds, /// but if the underlying capability does not actually implement `T`'s interface, /// then method calls will fail with "unimplemented" errors. - fn cast_to(self) -> T where Self: Sized { + fn cast_to(self) -> T + where + Self: Sized, + { FromClientHook::new(self.into_client_hook()) } } /// An untyped client. pub struct Client { - pub hook: Box + pub hook: Box, } impl Client { @@ -245,13 +277,17 @@ impl Client { Client { hook } } - pub fn new_call(&self, - interface_id : u64, - method_id : u16, - size_hint : Option) - -> Request { + pub fn new_call( + &self, + interface_id: u64, + method_id: u16, + size_hint: Option, + ) -> Request { let typeless = self.hook.new_call(interface_id, method_id, size_hint); - Request { hook: typeless.hook, marker: PhantomData } + Request { + hook: typeless.hook, + marker: PhantomData, + } } /// If the capability is actually only a promise, the returned promise resolves once the @@ -266,16 +302,19 @@ impl Client { /// An untyped server. pub trait Server { - fn dispatch_call(&mut self, interface_id: u64, method_id: u16, - params: Params, - results: Results) - -> Promise<(), Error>; + fn dispatch_call( + &mut self, + interface_id: u64, + method_id: u16, + params: Params, + results: Results, + ) -> Promise<(), Error>; } /// Trait to track the relationship between generated Server traits and Client structs. -pub trait FromServer : FromClientHook { +pub trait FromServer: FromClientHook { // Implemented by the generated ServerDispatch struct. - type Dispatch: Server + 'static + core::ops::DerefMut; + type Dispatch: Server + 'static + core::ops::DerefMut; fn from_server(s: S) -> Self::Dispatch; } diff --git a/capnp/src/capability_list.rs b/capnp/src/capability_list.rs index 529cdc839..432a60f6c 100644 --- a/capnp/src/capability_list.rs +++ b/capnp/src/capability_list.rs @@ -23,88 +23,142 @@ use alloc::boxed::Box; use core::marker::PhantomData; -use crate::capability::{FromClientHook}; +use crate::capability::FromClientHook; use crate::private::capability::ClientHook; -use crate::private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, Pointer}; -use crate::traits::{FromPointerReader, FromPointerBuilder, IndexMove, ListIter}; +use crate::private::layout::{ListBuilder, ListReader, Pointer, PointerBuilder, PointerReader}; +use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter}; use crate::Result; #[derive(Copy, Clone)] -pub struct Owned where T: FromClientHook { +pub struct Owned +where + T: FromClientHook, +{ marker: PhantomData, } -impl crate::traits::Owned for Owned where T: FromClientHook { +impl crate::traits::Owned for Owned +where + T: FromClientHook, +{ type Reader<'a> = Reader<'a, T>; type Builder<'a> = Builder<'a, T>; } -pub struct Reader<'a, T> where T: FromClientHook { +pub struct Reader<'a, T> +where + T: FromClientHook, +{ marker: PhantomData, - reader: ListReader<'a> + reader: ListReader<'a>, } -impl <'a, T> Clone for Reader<'a, T> where T: FromClientHook { +impl<'a, T> Clone for Reader<'a, T> +where + T: FromClientHook, +{ fn clone(&self) -> Reader<'a, T> { - Reader { marker : self.marker, reader : self.reader } + Reader { + marker: self.marker, + reader: self.reader, + } } } -impl <'a, T> Copy for Reader<'a, T> where T: FromClientHook {} +impl<'a, T> Copy for Reader<'a, T> where T: FromClientHook {} -impl <'a, T> Reader<'a, T> where T: FromClientHook { - pub fn len(&self) -> u32 { self.reader.len() } +impl<'a, T> Reader<'a, T> +where + T: FromClientHook, +{ + pub fn len(&self) -> u32 { + self.reader.len() + } pub fn iter(self) -> ListIter, Result> { ListIter::new(self, self.len()) } } - -impl <'a, T> Reader<'a, T> where T: FromClientHook { - pub fn reborrow(&self) -> Reader<'_, T> { - Reader { reader: self.reader, marker: PhantomData } +impl<'a, T> Reader<'a, T> +where + T: FromClientHook, +{ + pub fn reborrow(&self) -> Reader<'_, T> { + Reader { + reader: self.reader, + marker: PhantomData, + } } } -impl <'a, T> FromPointerReader<'a> for Reader<'a, T> where T: FromClientHook { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader: reader.get_list(Pointer, default)?, - marker: PhantomData }) +impl<'a, T> FromPointerReader<'a> for Reader<'a, T> +where + T: FromClientHook, +{ + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(Pointer, default)?, + marker: PhantomData, + }) } } -impl <'a, T> Reader<'a, T> where T: FromClientHook { +impl<'a, T> Reader<'a, T> +where + T: FromClientHook, +{ /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(self, index: u32) -> Result { assert!(index < self.len()); - Ok(FromClientHook::new(self.reader.get_pointer_element(index).get_capability()?)) + Ok(FromClientHook::new( + self.reader.get_pointer_element(index).get_capability()?, + )) } /// Gets the element at position `index`. Returns `None` if `index` /// is greater than or equal to `len()`. pub fn try_get(self, index: u32) -> Option> { if index < self.len() { - Some(self.reader.get_pointer_element(index).get_capability().map(FromClientHook::new)) + Some( + self.reader + .get_pointer_element(index) + .get_capability() + .map(FromClientHook::new), + ) } else { None } } } -impl <'a, T> IndexMove> for Reader<'a, T> where T: FromClientHook { +impl<'a, T> IndexMove> for Reader<'a, T> +where + T: FromClientHook, +{ fn index_move(&self, index: u32) -> Result { self.get(index) } } -pub struct Builder<'a, T> where T: FromClientHook { +pub struct Builder<'a, T> +where + T: FromClientHook, +{ marker: PhantomData, - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a, T> Builder<'a, T> where T: FromClientHook { - pub fn len(&self) -> u32 { self.builder.len() } +impl<'a, T> Builder<'a, T> +where + T: FromClientHook, +{ + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn into_reader(self) -> Reader<'a, T> { Reader { @@ -115,62 +169,91 @@ impl <'a, T> Builder<'a, T> where T: FromClientHook { pub fn set(&mut self, index: u32, value: Box) { assert!(index < self.len()); - self.builder.reborrow().get_pointer_element(index).set_capability(value); + self.builder + .reborrow() + .get_pointer_element(index) + .set_capability(value); } } -impl <'a, T> Builder<'a, T> where T: FromClientHook { +impl<'a, T> Builder<'a, T> +where + T: FromClientHook, +{ pub fn reborrow(&mut self) -> Builder<'_, T> { - Builder { builder: self.builder, marker: PhantomData } + Builder { + builder: self.builder, + marker: PhantomData, + } } } -impl <'a, T> FromPointerBuilder<'a> for Builder<'a, T> where T: FromClientHook { +impl<'a, T> FromPointerBuilder<'a> for Builder<'a, T> +where + T: FromClientHook, +{ fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> { Builder { marker: PhantomData, builder: builder.init_list(Pointer, size), } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { Ok(Builder { marker: PhantomData, - builder: builder.get_list(Pointer, default)? + builder: builder.get_list(Pointer, default)?, }) } } -impl <'a, T> Builder<'a, T> where T: FromClientHook { +impl<'a, T> Builder<'a, T> +where + T: FromClientHook, +{ /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(self, index: u32) -> Result { assert!(index < self.len()); - Ok(FromClientHook::new(self.builder.get_pointer_element(index).get_capability()?)) + Ok(FromClientHook::new( + self.builder.get_pointer_element(index).get_capability()?, + )) } /// Gets the element at position `index`. Returns `None` if `index` /// is greater than or equal to `len()`. pub fn try_get(self, index: u32) -> Option> { if index < self.len() { - Some(self.builder.get_pointer_element(index).get_capability().map(FromClientHook::new)) + Some( + self.builder + .get_pointer_element(index) + .get_capability() + .map(FromClientHook::new), + ) } else { None } } } -impl <'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> - where T: FromClientHook +impl<'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> +where + T: FromClientHook, { - fn set_pointer_builder<'b>(pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a, T>, - canonicalize: bool) -> Result<()> { + fn set_pointer_builder<'b>( + pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a, T>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize) } } -impl <'a, T> ::core::iter::IntoIterator for Reader<'a, T> - where T: FromClientHook +impl<'a, T> ::core::iter::IntoIterator for Reader<'a, T> +where + T: FromClientHook, { type Item = Result; type IntoIter = ListIter, Self::Item>; @@ -179,4 +262,3 @@ impl <'a, T> ::core::iter::IntoIterator for Reader<'a, T> self.iter() } } - diff --git a/capnp/src/constant.rs b/capnp/src/constant.rs index efbd74bf1..c7e0e7873 100644 --- a/capnp/src/constant.rs +++ b/capnp/src/constant.rs @@ -28,7 +28,7 @@ use core::marker::PhantomData; use crate::any_pointer; use crate::private::layout::PointerReader; use crate::traits::Owned; -use crate::{Result}; +use crate::Result; #[derive(Copy, Clone)] #[repr(C, align(8))] @@ -40,9 +40,15 @@ pub struct Reader { pub words: &'static [crate::Word], } -impl Reader where T: Owned { +impl Reader +where + T: Owned, +{ /// Retrieve the value. pub fn get(&self) -> Result<::Reader<'static>> { - any_pointer::Reader::new(PointerReader::get_root_unchecked(self.words.as_ptr() as *const u8)).get_as() + any_pointer::Reader::new(PointerReader::get_root_unchecked( + self.words.as_ptr() as *const u8 + )) + .get_as() } } diff --git a/capnp/src/data.rs b/capnp/src/data.rs index 324037987..b0d2a1cbf 100644 --- a/capnp/src/data.rs +++ b/capnp/src/data.rs @@ -38,8 +38,11 @@ pub(crate) unsafe fn reader_from_raw_parts<'a>(p: *const u8, len: u32) -> Reader ::core::slice::from_raw_parts(p, len as usize) } -impl <'a> crate::traits::FromPointerReader<'a> for Reader<'a> { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { +impl<'a> crate::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { reader.get_data(default) } } @@ -50,21 +53,25 @@ pub(crate) unsafe fn builder_from_raw_parts<'a>(p: *mut u8, len: u32) -> Builder ::core::slice::from_raw_parts_mut(p, len as usize) } -impl <'a> crate::traits::FromPointerBuilder<'a> for Builder<'a> { - fn init_pointer(builder : PointerBuilder<'a>, size : u32) -> Builder<'a> { +impl<'a> crate::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a> { builder.init_data(size) } - fn get_from_pointer(builder :PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { builder.get_data(default) } } -impl <'a> crate::traits::SetPointerBuilder for Reader<'a> { - fn set_pointer_builder<'b>(pointer: PointerBuilder<'b>, - value: Reader<'a>, - _canonicalize: bool) -> Result<()> { +impl<'a> crate::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder<'b>( + pointer: PointerBuilder<'b>, + value: Reader<'a>, + _canonicalize: bool, + ) -> Result<()> { pointer.set_data(value); Ok(()) } } - diff --git a/capnp/src/data_list.rs b/capnp/src/data_list.rs index 24c383136..51bc63092 100644 --- a/capnp/src/data_list.rs +++ b/capnp/src/data_list.rs @@ -21,8 +21,8 @@ //! List of sequences of bytes. -use crate::traits::{FromPointerReader, FromPointerBuilder, IndexMove, ListIter}; use crate::private::layout::*; +use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter}; use crate::Result; #[derive(Copy, Clone)] @@ -35,46 +35,53 @@ impl crate::traits::Owned for Owned { #[derive(Clone, Copy)] pub struct Reader<'a> { - pub reader: ListReader<'a> + pub reader: ListReader<'a>, } -impl <'a> Reader<'a> { +impl<'a> Reader<'a> { pub fn new(reader: ListReader<'_>) -> Reader<'_> { Reader { reader } } - pub fn len(&self) -> u32 { self.reader.len() } + pub fn len(&self) -> u32 { + self.reader.len() + } - pub fn iter(self) -> ListIter, Result>>{ + pub fn iter(self) -> ListIter, Result>> { let l = self.len(); ListIter::new(self, l) } } -impl <'a> FromPointerReader<'a> for Reader<'a> { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader: reader.get_list(Pointer, default)? }) +impl<'a> FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(Pointer, default)?, + }) } } -impl <'a> IndexMove>> for Reader<'a>{ +impl<'a> IndexMove>> for Reader<'a> { fn index_move(&self, index: u32) -> Result> { self.get(index) } } -impl <'a> Reader<'a> { +impl<'a> Reader<'a> { /// Gets the `data::Reader` at position `index`. Panics if `index` is /// greater than or equal to `len()`. - pub fn get(self, index : u32) -> Result> { - assert!(index < self.len()); + pub fn get(self, index: u32) -> Result> { + assert!(index < self.len()); self.reader.get_pointer_element(index).get_data(None) } /// Gets the `data::Reader` at position `index`. Returns `None` if `index` /// is greater than or equal to `len()`. - pub fn try_get(self, index : u32) -> Option>> { - if index < self.len() { + pub fn try_get(self, index: u32) -> Option>> { + if index < self.len() { Some(self.reader.get_pointer_element(index).get_data(None)) } else { None @@ -82,53 +89,64 @@ impl <'a> Reader<'a> { } } -impl <'a> crate::traits::IntoInternalListReader<'a> for Reader<'a> { +impl<'a> crate::traits::IntoInternalListReader<'a> for Reader<'a> { fn into_internal_list_reader(self) -> ListReader<'a> { self.reader } } pub struct Builder<'a> { - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a> Builder<'a> { +impl<'a> Builder<'a> { pub fn new(builder: ListBuilder<'a>) -> Builder<'a> { Builder { builder } } - pub fn len(&self) -> u32 { self.builder.len() } + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn into_reader(self) -> Reader<'a> { - Reader { reader: self.builder.into_reader() } + Reader { + reader: self.builder.into_reader(), + } } pub fn set(&mut self, index: u32, value: crate::data::Reader) { assert!(index < self.len()); - self.builder.reborrow().get_pointer_element(index).set_data(value); + self.builder + .reborrow() + .get_pointer_element(index) + .set_data(value); } pub fn reborrow(&mut self) -> Builder<'_> { - Builder {builder: self.builder.reborrow()} + Builder { + builder: self.builder.reborrow(), + } } } - -impl <'a> FromPointerBuilder<'a> for Builder<'a> { - fn init_pointer(builder: PointerBuilder<'a>, size : u32) -> Builder<'a> { +impl<'a> FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a> { Builder { - builder: builder.init_list(Pointer, size) + builder: builder.init_list(Pointer, size), } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { Ok(Builder { - builder: builder.get_list(Pointer, default)? + builder: builder.get_list(Pointer, default)?, }) } } -impl <'a> Builder<'a> { +impl<'a> Builder<'a> { /// Gets the `data::Builder` at position `index`. Panics if `index` is /// greater than or equal to `len()`. pub fn get(self, index: u32) -> Result> { @@ -147,17 +165,18 @@ impl <'a> Builder<'a> { } } - -impl <'a> crate::traits::SetPointerBuilder for Reader<'a> { - fn set_pointer_builder<'b>(pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a>, - canonicalize: bool) -> Result<()> { +impl<'a> crate::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder<'b>( + pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize)?; Ok(()) } } -impl <'a> ::core::iter::IntoIterator for Reader<'a> { +impl<'a> ::core::iter::IntoIterator for Reader<'a> { type Item = Result>; type IntoIter = ListIter, Self::Item>; diff --git a/capnp/src/enum_list.rs b/capnp/src/enum_list.rs index a3086b80e..300dff1d0 100644 --- a/capnp/src/enum_list.rs +++ b/capnp/src/enum_list.rs @@ -21,10 +21,10 @@ //! List of enums. -use crate::traits::{FromPointerReader, FromPointerBuilder, - ToU16, FromU16, ListIter, IndexMove}; -use crate::private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, - TwoBytes, PrimitiveElement}; +use crate::private::layout::{ + ListBuilder, ListReader, PointerBuilder, PointerReader, PrimitiveElement, TwoBytes, +}; +use crate::traits::{FromPointerBuilder, FromPointerReader, FromU16, IndexMove, ListIter, ToU16}; use crate::{NotInSchema, Result}; use core::marker::PhantomData; @@ -34,7 +34,10 @@ pub struct Owned { marker: PhantomData, } -impl crate::traits::Owned for Owned where T: FromU16 { +impl crate::traits::Owned for Owned +where + T: FromU16, +{ type Reader<'a> = Reader<'a, T>; type Builder<'a> = Builder<'a, T>; } @@ -42,32 +45,39 @@ impl crate::traits::Owned for Owned where T: FromU16 { #[derive(Clone, Copy)] pub struct Reader<'a, T> { marker: PhantomData, - reader: ListReader<'a> + reader: ListReader<'a>, } -impl <'a, T: FromU16> Reader<'a, T> { - pub fn len(&self) -> u32 { self.reader.len() } +impl<'a, T: FromU16> Reader<'a, T> { + pub fn len(&self) -> u32 { + self.reader.len() + } - pub fn iter(self) -> ListIter, ::core::result::Result>{ + pub fn iter(self) -> ListIter, ::core::result::Result> { let l = self.len(); ListIter::new(self, l) } } -impl <'a, T : FromU16> FromPointerReader<'a> for Reader<'a, T> { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader: reader.get_list(TwoBytes, default)?, - marker: PhantomData }) +impl<'a, T: FromU16> FromPointerReader<'a> for Reader<'a, T> { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(TwoBytes, default)?, + marker: PhantomData, + }) } } -impl <'a, T: FromU16> IndexMove> for Reader<'a, T>{ +impl<'a, T: FromU16> IndexMove> for Reader<'a, T> { fn index_move(&self, index: u32) -> ::core::result::Result { self.get(index) } } -impl <'a, T : FromU16> Reader<'a, T> { +impl<'a, T: FromU16> Reader<'a, T> { /// Gets the `T` at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(&self, index: u32) -> ::core::result::Result { @@ -88,7 +98,10 @@ impl <'a, T : FromU16> Reader<'a, T> { } } -impl <'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> where T: PrimitiveElement { +impl<'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> +where + T: PrimitiveElement, +{ fn into_internal_list_reader(self) -> ListReader<'a> { self.reader } @@ -96,14 +109,19 @@ impl <'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> where T pub struct Builder<'a, T> { marker: PhantomData, - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a, T : ToU16 + FromU16> Builder<'a, T> { - pub fn len(&self) -> u32 { self.builder.len() } +impl<'a, T: ToU16 + FromU16> Builder<'a, T> { + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn into_reader(self) -> Reader<'a, T> { - Reader { reader: self.builder.into_reader(), marker: PhantomData, } + Reader { + reader: self.builder.into_reader(), + marker: PhantomData, + } } pub fn set(&mut self, index: u32, value: T) { @@ -112,18 +130,25 @@ impl <'a, T : ToU16 + FromU16> Builder<'a, T> { } } -impl <'a, T : FromU16> FromPointerBuilder<'a> for Builder<'a, T> { +impl<'a, T: FromU16> FromPointerBuilder<'a> for Builder<'a, T> { fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> { - Builder { builder: builder.init_list(TwoBytes, size), - marker: PhantomData } + Builder { + builder: builder.init_list(TwoBytes, size), + marker: PhantomData, + } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Builder { builder: builder.get_list(TwoBytes, default)?, - marker: PhantomData }) + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Builder { + builder: builder.get_list(TwoBytes, default)?, + marker: PhantomData, + }) } } -impl <'a, T : ToU16 + FromU16> Builder<'a, T> { +impl<'a, T: ToU16 + FromU16> Builder<'a, T> { /// Gets the `T` at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(&self, index: u32) -> ::core::result::Result { @@ -144,19 +169,21 @@ impl <'a, T : ToU16 + FromU16> Builder<'a, T> { } pub fn reborrow(&self) -> Builder<'_, T> { - Builder { .. *self } + Builder { ..*self } } } -impl <'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> { - fn set_pointer_builder<'b>(pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a, T>, - canonicalize: bool) -> Result<()> { +impl<'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> { + fn set_pointer_builder<'b>( + pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a, T>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize) } } -impl <'a, T: FromU16> ::core::iter::IntoIterator for Reader<'a, T> { +impl<'a, T: FromU16> ::core::iter::IntoIterator for Reader<'a, T> { type Item = ::core::result::Result; type IntoIter = ListIter, Self::Item>; diff --git a/capnp/src/io.rs b/capnp/src/io.rs index 56b3c247b..03279571d 100644 --- a/capnp/src/io.rs +++ b/capnp/src/io.rs @@ -26,7 +26,9 @@ pub trait Read { } } if !buf.is_empty() { - Err(crate::Error::failed("failed to fill the whole buffer".to_string())) + Err(crate::Error::failed( + "failed to fill the whole buffer".to_string(), + )) } else { Ok(()) } @@ -34,7 +36,7 @@ pub trait Read { } /// A rough approximation of std::io::BufRead. -pub trait BufRead : Read { +pub trait BufRead: Read { fn fill_buf(&mut self) -> Result<&[u8]>; fn consume(&mut self, amt: usize); } @@ -44,12 +46,15 @@ pub trait Write { fn write_all(&mut self, buf: &[u8]) -> Result<()>; } -#[cfg(feature="std")] +#[cfg(feature = "std")] mod std_impls { - use crate::{Result}; - use crate::io::{Read, BufRead, Write}; + use crate::io::{BufRead, Read, Write}; + use crate::Result; - impl Read for R where R: std::io::Read { + impl Read for R + where + R: std::io::Read, + { fn read(&mut self, buf: &mut [u8]) -> Result { loop { match std::io::Read::read(self, buf) { @@ -61,7 +66,10 @@ mod std_impls { } } - impl BufRead for R where R: std::io::BufRead { + impl BufRead for R + where + R: std::io::BufRead, + { fn fill_buf(&mut self) -> Result<&[u8]> { Ok(std::io::BufRead::fill_buf(self)?) } @@ -70,7 +78,10 @@ mod std_impls { } } - impl Write for W where W: std::io::Write { + impl Write for W + where + W: std::io::Write, + { fn write_all(&mut self, buf: &[u8]) -> Result<()> { std::io::Write::write_all(self, buf)?; Ok(()) @@ -78,13 +89,13 @@ mod std_impls { } } -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] mod no_std_impls { - use alloc::string::ToString; + use crate::io::{BufRead, Read, Write}; use crate::{Error, Result}; - use crate::io::{Read, BufRead, Write}; + use alloc::string::ToString; - impl <'a> Write for &'a mut [u8] { + impl<'a> Write for &'a mut [u8] { fn write_all(&mut self, buf: &[u8]) -> Result<()> { if buf.len() > self.len() { return Err(Error::failed("buffer is not large enough".to_string())); @@ -104,13 +115,16 @@ mod no_std_impls { } } - impl Write for &mut W where W: Write { + impl Write for &mut W + where + W: Write, + { fn write_all(&mut self, buf: &[u8]) -> Result<()> { (**self).write_all(buf) } } - impl <'a> Read for &'a [u8] { + impl<'a> Read for &'a [u8] { fn read(&mut self, buf: &mut [u8]) -> Result { let amt = core::cmp::min(buf.len(), self.len()); let (a, b) = self.split_at(amt); @@ -121,13 +135,16 @@ mod no_std_impls { } } - impl Read for &mut R where R: Read { + impl Read for &mut R + where + R: Read, + { fn read(&mut self, buf: &mut [u8]) -> Result { (**self).read(buf) } } - impl <'a> BufRead for &'a [u8] { + impl<'a> BufRead for &'a [u8] { fn fill_buf(&mut self) -> Result<&[u8]> { Ok(*self) } @@ -136,7 +153,10 @@ mod no_std_impls { } } - impl BufRead for &mut R where R: BufRead { + impl BufRead for &mut R + where + R: BufRead, + { fn fill_buf(&mut self) -> Result<&[u8]> { (**self).fill_buf() } diff --git a/capnp/src/lib.rs b/capnp/src/lib.rs index f30cbff06..54ecf8746 100644 --- a/capnp/src/lib.rs +++ b/capnp/src/lib.rs @@ -64,46 +64,46 @@ use alloc::vec::Vec; #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(C, align(8))] pub struct Word { - raw_content: [u8; 8] + raw_content: [u8; 8], } /// /// Constructs a word with the given bytes. /// pub const fn word(b0: u8, b1: u8, b2: u8, b3: u8, b4: u8, b5: u8, b6: u8, b7: u8) -> Word { - Word { raw_content: [b0,b1,b2,b3,b4,b5,b6,b7] } + Word { + raw_content: [b0, b1, b2, b3, b4, b5, b6, b7], + } } impl Word { /// Allocates a vec of `length` words, all set to zero. pub fn allocate_zeroed_vec(length: usize) -> Vec { - vec![word(0,0,0,0,0,0,0,0); length] + vec![word(0, 0, 0, 0, 0, 0, 0, 0); length] } pub fn words_to_bytes(words: &[Word]) -> &[u8] { - unsafe { - core::slice::from_raw_parts(words.as_ptr() as *const u8, words.len() * 8) - } + unsafe { core::slice::from_raw_parts(words.as_ptr() as *const u8, words.len() * 8) } } pub fn words_to_bytes_mut(words: &mut [Word]) -> &mut [u8] { - unsafe { - core::slice::from_raw_parts_mut(words.as_mut_ptr() as *mut u8, words.len() * 8) - } + unsafe { core::slice::from_raw_parts_mut(words.as_mut_ptr() as *mut u8, words.len() * 8) } } } -#[cfg(any(feature="quickcheck", test))] +#[cfg(any(feature = "quickcheck", test))] impl quickcheck::Arbitrary for Word { fn arbitrary(g: &mut quickcheck::Gen) -> Word { - crate::word(quickcheck::Arbitrary::arbitrary(g), - quickcheck::Arbitrary::arbitrary(g), - quickcheck::Arbitrary::arbitrary(g), - quickcheck::Arbitrary::arbitrary(g), - quickcheck::Arbitrary::arbitrary(g), - quickcheck::Arbitrary::arbitrary(g), - quickcheck::Arbitrary::arbitrary(g), - quickcheck::Arbitrary::arbitrary(g)) + crate::word( + quickcheck::Arbitrary::arbitrary(g), + quickcheck::Arbitrary::arbitrary(g), + quickcheck::Arbitrary::arbitrary(g), + quickcheck::Arbitrary::arbitrary(g), + quickcheck::Arbitrary::arbitrary(g), + quickcheck::Arbitrary::arbitrary(g), + quickcheck::Arbitrary::arbitrary(g), + quickcheck::Arbitrary::arbitrary(g), + ) } } @@ -113,7 +113,7 @@ pub struct MessageSize { pub word_count: u64, /// Size of the capability table. - pub cap_count: u32 + pub cap_count: u32, } impl core::ops::AddAssign for MessageSize { @@ -128,12 +128,19 @@ impl core::ops::AddAssign for MessageSize { pub struct NotInSchema(pub u16); impl ::core::fmt::Display for NotInSchema { - fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> ::core::result::Result<(), ::core::fmt::Error> { - write!(fmt, "Enum value or union discriminant {} was not present in the schema.", self.0) + fn fmt( + &self, + fmt: &mut ::core::fmt::Formatter, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + write!( + fmt, + "Enum value or union discriminant {} was not present in the schema.", + self.0 + ) } } -#[cfg(feature="std")] +#[cfg(feature = "std")] impl ::std::error::Error for NotInSchema { fn description(&self) -> &str { "Enum value or union discriminant was not present in schema." @@ -181,33 +188,48 @@ pub enum ErrorKind { impl Error { pub fn failed(description: String) -> Error { - Error { description, kind: ErrorKind::Failed } + Error { + description, + kind: ErrorKind::Failed, + } } pub fn overloaded(description: String) -> Error { - Error { description, kind: ErrorKind::Overloaded } + Error { + description, + kind: ErrorKind::Overloaded, + } } pub fn disconnected(description: String) -> Error { - Error { description, kind: ErrorKind::Disconnected } + Error { + description, + kind: ErrorKind::Disconnected, + } } pub fn unimplemented(description: String) -> Error { - Error { description, kind: ErrorKind::Unimplemented } + Error { + description, + kind: ErrorKind::Unimplemented, + } } } -#[cfg(feature="std")] +#[cfg(feature = "std")] impl core::convert::From<::std::io::Error> for Error { fn from(err: ::std::io::Error) -> Error { use std::io; let kind = match err.kind() { io::ErrorKind::TimedOut => ErrorKind::Overloaded, - io::ErrorKind::BrokenPipe | - io::ErrorKind::ConnectionRefused | - io::ErrorKind::ConnectionReset | - io::ErrorKind::ConnectionAborted | - io::ErrorKind::NotConnected => ErrorKind::Disconnected, + io::ErrorKind::BrokenPipe + | io::ErrorKind::ConnectionRefused + | io::ErrorKind::ConnectionReset + | io::ErrorKind::ConnectionAborted + | io::ErrorKind::NotConnected => ErrorKind::Disconnected, _ => ErrorKind::Failed, }; - Error { description: format!("{}", err), kind } + Error { + description: format!("{}", err), + kind, + } } } @@ -225,7 +247,10 @@ impl core::convert::From for Error { impl core::convert::From for Error { fn from(e: NotInSchema) -> Error { - Error::failed(format!("Enum value or union discriminant {} was not present in schema.", e.0)) + Error::failed(format!( + "Enum value or union discriminant {} was not present in schema.", + e.0 + )) } } @@ -235,7 +260,7 @@ impl core::fmt::Display for Error { } } -#[cfg(feature="std")] +#[cfg(feature = "std")] impl ::std::error::Error for Error { fn description(&self) -> &str { &self.description @@ -252,16 +277,12 @@ pub enum OutputSegments<'a> { MultiSegment(Vec<&'a [u8]>), } -impl <'a> core::ops::Deref for OutputSegments<'a> { +impl<'a> core::ops::Deref for OutputSegments<'a> { type Target = [&'a [u8]]; fn deref(&self) -> &[&'a [u8]] { match *self { - OutputSegments::SingleSegment(ref s) => { - s - } - OutputSegments::MultiSegment(ref v) => { - v - } + OutputSegments::SingleSegment(ref s) => s, + OutputSegments::MultiSegment(ref v) => v, } } } @@ -269,12 +290,8 @@ impl <'a> core::ops::Deref for OutputSegments<'a> { impl<'s> message::ReaderSegments for OutputSegments<'s> { fn get_segment(&self, id: u32) -> Option<&[u8]> { match *self { - OutputSegments::SingleSegment(ref s) => { - s.get(id as usize).copied() - } - OutputSegments::MultiSegment(ref v) => { - v.get(id as usize).copied() - } + OutputSegments::SingleSegment(ref s) => s.get(id as usize).copied(), + OutputSegments::MultiSegment(ref v) => v.get(id as usize).copied(), } } } diff --git a/capnp/src/list_list.rs b/capnp/src/list_list.rs index 8ba4c0f37..9c9f53f75 100644 --- a/capnp/src/list_list.rs +++ b/capnp/src/list_list.rs @@ -21,120 +21,188 @@ //! List of lists. -use crate::traits::{FromPointerReader, FromPointerBuilder, ListIter, IndexMove}; -use crate::private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, Pointer}; +use crate::private::layout::{ListBuilder, ListReader, Pointer, PointerBuilder, PointerReader}; +use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter}; use crate::Result; #[derive(Clone, Copy)] -pub struct Owned where T: crate::traits::Owned { +pub struct Owned +where + T: crate::traits::Owned, +{ marker: ::core::marker::PhantomData, } -impl crate::traits::Owned for Owned where T: crate::traits::Owned { +impl crate::traits::Owned for Owned +where + T: crate::traits::Owned, +{ type Reader<'a> = Reader<'a, T>; type Builder<'a> = Builder<'a, T>; } -pub struct Reader<'a, T> where T: crate::traits::Owned { +pub struct Reader<'a, T> +where + T: crate::traits::Owned, +{ marker: ::core::marker::PhantomData>, - reader: ListReader<'a> + reader: ListReader<'a>, } -impl <'a, T> Reader<'a, T> where T: crate::traits::Owned { - pub fn len(&self) -> u32 { self.reader.len() } +impl<'a, T> Reader<'a, T> +where + T: crate::traits::Owned, +{ + pub fn len(&self) -> u32 { + self.reader.len() + } pub fn iter(self) -> ListIter, Result>> { ListIter::new(self, self.len()) } } -impl <'a, T> Clone for Reader<'a, T> where T: crate::traits::Owned { +impl<'a, T> Clone for Reader<'a, T> +where + T: crate::traits::Owned, +{ fn clone(&self) -> Reader<'a, T> { - Reader { marker : self.marker, reader : self.reader } + Reader { + marker: self.marker, + reader: self.reader, + } } } -impl <'a, T> Copy for Reader<'a, T> where T: crate::traits::Owned {} +impl<'a, T> Copy for Reader<'a, T> where T: crate::traits::Owned {} -impl <'a, T> IndexMove>> for Reader<'a, T> -where T: crate::traits::Owned { - fn index_move(&self, index : u32) -> Result> { +impl<'a, T> IndexMove>> for Reader<'a, T> +where + T: crate::traits::Owned, +{ + fn index_move(&self, index: u32) -> Result> { self.get(index) } } -impl <'a, T> FromPointerReader<'a> for Reader<'a, T> where T: crate::traits::Owned { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader: reader.get_list(Pointer, default)?, - marker: ::core::marker::PhantomData }) +impl<'a, T> FromPointerReader<'a> for Reader<'a, T> +where + T: crate::traits::Owned, +{ + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(Pointer, default)?, + marker: ::core::marker::PhantomData, + }) } } -impl <'a, T> Reader<'a, T> where T: crate::traits::Owned { +impl<'a, T> Reader<'a, T> +where + T: crate::traits::Owned, +{ /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(self, index: u32) -> Result> { - assert!(index < self.len()); + assert!(index < self.len()); FromPointerReader::get_from_pointer(&self.reader.get_pointer_element(index), None) } /// Gets the element at position `index`. Returns `None` if `index` /// is greater than or equal to `len()`. pub fn try_get(self, index: u32) -> Option>> { - if index < self.len() { - Some(FromPointerReader::get_from_pointer(&self.reader.get_pointer_element(index), None)) + if index < self.len() { + Some(FromPointerReader::get_from_pointer( + &self.reader.get_pointer_element(index), + None, + )) } else { None } } } -impl <'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> where T: crate::traits::Owned { +impl<'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> +where + T: crate::traits::Owned, +{ fn into_internal_list_reader(self) -> ListReader<'a> { self.reader } } -pub struct Builder<'a, T> where T: crate::traits::Owned { +pub struct Builder<'a, T> +where + T: crate::traits::Owned, +{ marker: ::core::marker::PhantomData, - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a, T> Builder<'a, T> where T: crate::traits::Owned { - pub fn len(&self) -> u32 { self.builder.len() } +impl<'a, T> Builder<'a, T> +where + T: crate::traits::Owned, +{ + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn into_reader(self) -> Reader<'a, T> { - Reader { reader: self.builder.into_reader(), marker: ::core::marker::PhantomData } + Reader { + reader: self.builder.into_reader(), + marker: ::core::marker::PhantomData, + } } } -impl <'a, T> Builder<'a, T> where T: crate::traits::Owned { +impl<'a, T> Builder<'a, T> +where + T: crate::traits::Owned, +{ pub fn init(self, index: u32, size: u32) -> T::Builder<'a> { FromPointerBuilder::init_pointer(self.builder.get_pointer_element(index), size) } } -impl <'a, T> Builder<'a, T> where T: crate::traits::Owned { +impl<'a, T> Builder<'a, T> +where + T: crate::traits::Owned, +{ pub fn reborrow(&mut self) -> Builder<'_, T> { - Builder {builder: self.builder.reborrow(), marker: ::core::marker::PhantomData} + Builder { + builder: self.builder.reborrow(), + marker: ::core::marker::PhantomData, + } } } -impl <'a, T> FromPointerBuilder<'a> for Builder<'a, T> where T: crate::traits::Owned { - fn init_pointer(builder: PointerBuilder<'a>, size : u32) -> Builder<'a, T> { +impl<'a, T> FromPointerBuilder<'a> for Builder<'a, T> +where + T: crate::traits::Owned, +{ + fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> { Builder { marker: ::core::marker::PhantomData, - builder: builder.init_list(Pointer, size) + builder: builder.init_list(Pointer, size), } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { Ok(Builder { marker: ::core::marker::PhantomData, - builder: builder.get_list(Pointer, default)? + builder: builder.get_list(Pointer, default)?, }) } } -impl <'a, T> Builder<'a, T> where T: crate::traits::Owned { +impl<'a, T> Builder<'a, T> +where + T: crate::traits::Owned, +{ /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(self, index: u32) -> Result> { @@ -146,32 +214,43 @@ impl <'a, T> Builder<'a, T> where T: crate::traits::Owned { /// is greater than or equal to `len()`. pub fn try_get(self, index: u32) -> Option>> { if index < self.len() { - Some(FromPointerBuilder::get_from_pointer(self.builder.get_pointer_element(index), None)) + Some(FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_element(index), + None, + )) } else { None } } pub fn set<'b>(&self, index: u32, value: T::Reader<'a>) -> Result<()> - where T::Reader<'a>: crate::traits::IntoInternalListReader<'b> + where + T::Reader<'a>: crate::traits::IntoInternalListReader<'b>, { use crate::traits::IntoInternalListReader; assert!(index < self.len()); - self.builder.get_pointer_element(index).set_list(&value.into_internal_list_reader(), false) + self.builder + .get_pointer_element(index) + .set_list(&value.into_internal_list_reader(), false) } } -impl <'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> - where T:crate::traits::Owned +impl<'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> +where + T: crate::traits::Owned, { - fn set_pointer_builder<'b>(pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a, T>, - canonicalize: bool) -> Result<()> { + fn set_pointer_builder<'b>( + pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a, T>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize) } } -impl <'a, T> ::core::iter::IntoIterator for Reader<'a, T> where T: crate::traits::Owned +impl<'a, T> ::core::iter::IntoIterator for Reader<'a, T> +where + T: crate::traits::Owned, { type Item = Result>; type IntoIter = ListIter, Self::Item>; diff --git a/capnp/src/message.rs b/capnp/src/message.rs index 3c4881818..f0abd67e9 100644 --- a/capnp/src/message.rs +++ b/capnp/src/message.rs @@ -42,26 +42,26 @@ //! [TypedReader] and [TypedBuilder] accept generic type parameter `T`. This parameter must be //! a corresponding `Owned` type which was auto-generated inside the corresponding module. //! -//! For example, for auto-generated module `crate::test_data::simple_struct` you'd supply +//! For example, for auto-generated module `crate::test_data::simple_struct` you'd supply //! `crate::test_data::simple_struct::Owned` type into [TypedReader]/[TypedBuilder] //! //! ```ignore //! include!(concat!(env!("OUT_DIR"), "/simple_struct_capnp.rs")); //! //! use capnp::message::{self, TypedBuilder, TypedReader}; -//! +//! //! fn main() { //! let mut builder = TypedBuilder::::new_default(); //! let mut builder_root = builder.init_root(); //! builder_root.set_x(10); //! builder_root.set_y(20); -//! +//! //! let mut buffer = vec![]; //! capnp::serialize_packed::write_message(&mut buffer, builder.borrow_inner()).unwrap(); -//! +//! //! let reader = capnp::serialize_packed::read_message(buffer.as_slice(), ReaderOptions::new()).unwrap(); //! let typed_reader = TypedReader::<_, simple_struct::Owned>::new(reader); -//! +//! //! let reader_root = typed_reader.get().unwrap(); //! assert_eq!(reader_root.get_x(), 10); //! assert_eq!(reader_root.get_x(), 20); @@ -72,16 +72,15 @@ use alloc::vec::Vec; use core::convert::From; use crate::any_pointer; -use crate::private::arena::{BuilderArenaImpl, ReaderArenaImpl, BuilderArena, ReaderArena}; +use crate::private::arena::{BuilderArena, BuilderArenaImpl, ReaderArena, ReaderArenaImpl}; use crate::private::layout; use crate::private::units::BYTES_PER_WORD; -use crate::traits::{FromPointerReader, FromPointerBuilder, SetPointerBuilder, Owned}; +use crate::traits::{FromPointerBuilder, FromPointerReader, Owned, SetPointerBuilder}; use crate::{OutputSegments, Result}; /// Options controlling how data is read. #[derive(Clone, Copy, Debug)] pub struct ReaderOptions { - /// Limits how many total (8-byte) words of data are allowed to be traversed. Traversal is counted /// when a new struct or list builder is obtained, e.g. from a get() accessor. This means that /// calling the getter for the same sub-struct multiple times will cause it to be double-counted. @@ -112,9 +111,10 @@ pub struct ReaderOptions { pub nesting_limit: i32, } -pub const DEFAULT_READER_OPTIONS: ReaderOptions = - ReaderOptions { traversal_limit_in_words: Some(8 * 1024 * 1024), nesting_limit: 64 }; - +pub const DEFAULT_READER_OPTIONS: ReaderOptions = ReaderOptions { + traversal_limit_in_words: Some(8 * 1024 * 1024), + nesting_limit: 64, +}; impl Default for ReaderOptions { fn default() -> ReaderOptions { @@ -123,7 +123,9 @@ impl Default for ReaderOptions { } impl ReaderOptions { - pub fn new() -> ReaderOptions { DEFAULT_READER_OPTIONS } + pub fn new() -> ReaderOptions { + DEFAULT_READER_OPTIONS + } pub fn nesting_limit(&mut self, value: i32) -> &mut ReaderOptions { self.nesting_limit = value; @@ -158,7 +160,10 @@ pub trait ReaderSegments { } } -impl ReaderSegments for &S where S: ReaderSegments { +impl ReaderSegments for &S +where + S: ReaderSegments, +{ fn get_segment(&self, idx: u32) -> Option<&[u8]> { (**self).get_segment(idx) } @@ -173,13 +178,13 @@ pub struct SegmentArray<'a> { segments: &'a [&'a [u8]], } -impl <'a> SegmentArray<'a> { +impl<'a> SegmentArray<'a> { pub fn new(segments: &'a [&'a [u8]]) -> SegmentArray<'a> { SegmentArray { segments } } } -impl <'b> ReaderSegments for SegmentArray<'b> { +impl<'b> ReaderSegments for SegmentArray<'b> { fn get_segment(&self, id: u32) -> Option<&[u8]> { self.segments.get(id as usize).copied() } @@ -189,7 +194,7 @@ impl <'b> ReaderSegments for SegmentArray<'b> { } } -impl <'b> ReaderSegments for [&'b [u8]] { +impl<'b> ReaderSegments for [&'b [u8]] { fn get_segment(&self, id: u32) -> Option<&[u8]> { self.get(id as usize).copied() } @@ -200,11 +205,17 @@ impl <'b> ReaderSegments for [&'b [u8]] { } /// A container used to read a message. -pub struct Reader where S: ReaderSegments { +pub struct Reader +where + S: ReaderSegments, +{ arena: ReaderArenaImpl, } -impl Reader where S: ReaderSegments { +impl Reader +where + S: ReaderSegments, +{ pub fn new(segments: S, options: ReaderOptions) -> Self { Reader { arena: ReaderArenaImpl::new(segments, options), @@ -214,7 +225,11 @@ impl Reader where S: ReaderSegments { fn get_root_internal(&self) -> Result> { let (segment_start, _seg_len) = self.arena.get_segment(0)?; let pointer_reader = layout::PointerReader::get_root( - &self.arena, 0, segment_start, self.arena.nesting_limit())?; + &self.arena, + 0, + segment_start, + self.arena.nesting_limit(), + )?; Ok(any_pointer::Reader::new(pointer_reader)) } @@ -236,15 +251,20 @@ impl Reader where S: ReaderSegments { // segments there are? // There is more than one segment, so the message cannot be canonical. - return Ok(false) + return Ok(false); } let pointer_reader = layout::PointerReader::get_root( - &self.arena, 0, segment_start, self.arena.nesting_limit())?; - let read_head = ::core::cell::Cell::new(unsafe {segment_start.add(BYTES_PER_WORD)}); + &self.arena, + 0, + segment_start, + self.arena.nesting_limit(), + )?; + let read_head = ::core::cell::Cell::new(unsafe { segment_start.add(BYTES_PER_WORD) }); let root_is_canonical = pointer_reader.is_canonical(&read_head)?; - let all_words_consumed = - (read_head.get() as usize - segment_start as usize) / BYTES_PER_WORD == seg_len as usize; + let all_words_consumed = (read_head.get() as usize - segment_start as usize) + / BYTES_PER_WORD + == seg_len as usize; Ok(root_is_canonical && all_words_consumed) } @@ -273,16 +293,19 @@ impl Reader where S: ReaderSegments { /// A message reader whose value is known to be of type `T`. /// Please see [module documentation](self) for more info about reader type specialization. pub struct TypedReader - where S: ReaderSegments, - T: Owned { +where + S: ReaderSegments, + T: Owned, +{ marker: ::core::marker::PhantomData, message: Reader, } -impl TypedReader - where S: ReaderSegments, - T : Owned { - +impl TypedReader +where + S: ReaderSegments, + T: Owned, +{ pub fn new(message: Reader) -> Self { TypedReader { marker: ::core::marker::PhantomData, @@ -299,35 +322,37 @@ impl TypedReader } } -impl From> for TypedReader - where S: ReaderSegments, - T: Owned { - +impl From> for TypedReader +where + S: ReaderSegments, + T: Owned, +{ fn from(message: Reader) -> TypedReader { TypedReader::new(message) } } -impl From> for TypedReader, T> - where A: Allocator, - T: Owned { - +impl From> for TypedReader, T> +where + A: Allocator, + T: Owned, +{ fn from(message: Builder) -> TypedReader, T> { let reader = message.into_reader(); reader.into_typed() } } -impl From> for TypedReader, T> - where A: Allocator, - T: Owned { - +impl From> for TypedReader, T> +where + A: Allocator, + T: Owned, +{ fn from(builder: TypedBuilder) -> TypedReader, T> { builder.into_reader() } } - /// An object that allocates memory for a Cap'n Proto message as it is being built. pub unsafe trait Allocator { /// Allocates zeroed memory for a new segment, returning a pointer to the start of the segment @@ -352,11 +377,14 @@ pub unsafe trait Allocator { } /// A container used to build a message. -pub struct Builder where A: Allocator { +pub struct Builder +where + A: Allocator, +{ arena: BuilderArenaImpl, } -unsafe impl Send for Builder where A: Send + Allocator {} +unsafe impl Send for Builder where A: Send + Allocator {} fn _assert_kinds() { fn _assert_send() {} @@ -368,7 +396,10 @@ fn _assert_kinds() { } } -impl Builder where A: Allocator { +impl Builder +where + A: Allocator, +{ pub fn new(allocator: A) -> Self { Builder { arena: BuilderArenaImpl::new(allocator), @@ -377,15 +408,16 @@ impl Builder where A: Allocator { fn get_root_internal(&mut self) -> any_pointer::Builder<'_> { if self.arena.len() == 0 { - self.arena.allocate_segment(1).expect("allocate root pointer"); + self.arena + .allocate_segment(1) + .expect("allocate root pointer"); self.arena.allocate(0, 1).expect("allocate root pointer"); } let (seg_start, _seg_len) = self.arena.get_segment_mut(0); let location: *mut u8 = seg_start; let Builder { ref mut arena } = *self; - any_pointer::Builder::new( - layout::PointerBuilder::get_root(arena, 0, location)) + any_pointer::Builder::new(layout::PointerBuilder::get_root(arena, 0, location)) } /// Initializes the root as a value of the given type. @@ -406,7 +438,11 @@ impl Builder where A: Allocator { } else { let (segment_start, _segment_len) = self.arena.get_segment(0)?; let pointer_reader = layout::PointerReader::get_root( - self.arena.as_reader(), 0, segment_start, 0x7fffffff)?; + self.arena.as_reader(), + 0, + segment_start, + 0x7fffffff, + )?; let root = any_pointer::Reader::new(pointer_reader); root.get_as() } @@ -421,10 +457,11 @@ impl Builder where A: Allocator { /// Sets the root to a canonicalized version of `value`. If this was the first action taken /// on this `Builder`, then a subsequent call to `get_segments_for_output()` should return /// a single segment, containing the full canonicalized message. - pub fn set_root_canonical(&mut self, value: From) -> Result<()> - { + pub fn set_root_canonical(&mut self, value: From) -> Result<()> { if self.arena.len() == 0 { - self.arena.allocate_segment(1).expect("allocate root pointer"); + self.arena + .allocate_segment(1) + .expect("allocate root pointer"); self.arena.allocate(0, 1).expect("allocate root pointer"); } let (seg_start, _seg_len) = self.arena.get_segment_mut(0); @@ -439,10 +476,13 @@ impl Builder where A: Allocator { } pub fn into_reader(self) -> Reader> { - Reader::new(self, ReaderOptions { - traversal_limit_in_words: None, - nesting_limit: i32::max_value() - }) + Reader::new( + self, + ReaderOptions { + traversal_limit_in_words: None, + nesting_limit: i32::max_value(), + }, + ) } pub fn into_typed(self) -> TypedBuilder { @@ -454,7 +494,10 @@ impl Builder where A: Allocator { } } -impl ReaderSegments for Builder where A: Allocator { +impl ReaderSegments for Builder +where + A: Allocator, +{ fn get_segment(&self, id: u32) -> Option<&[u8]> { self.get_segments_for_output().get(id as usize).copied() } @@ -465,9 +508,9 @@ impl ReaderSegments for Builder where A: Allocator { } /// Stongly typed variant of the [Builder] -/// +/// /// Generic type parameters: -/// - `T` - type of the capnp message which this builder is specialized on. Please see +/// - `T` - type of the capnp message which this builder is specialized on. Please see /// [module documentation](self) for more info about builder type specialization. /// - `A` - type of allocator pub struct TypedBuilder @@ -571,9 +614,11 @@ pub const SUGGESTED_ALLOCATION_STRATEGY: AllocationStrategy = AllocationStrategy impl HeapAllocator { pub fn new() -> HeapAllocator { - HeapAllocator { next_size: SUGGESTED_FIRST_SEGMENT_WORDS, - allocation_strategy: SUGGESTED_ALLOCATION_STRATEGY, - max_segment_words: 1 << 29, } + HeapAllocator { + next_size: SUGGESTED_FIRST_SEGMENT_WORDS, + allocation_strategy: SUGGESTED_ALLOCATION_STRATEGY, + max_segment_words: 1 << 29, + } } /// Sets the size of the initial segment in words, where 1 word = 8 bytes. @@ -600,10 +645,12 @@ impl HeapAllocator { unsafe impl Allocator for HeapAllocator { fn allocate_segment(&mut self, minimum_size: u32) -> (*mut u8, u32) { let size = core::cmp::max(minimum_size, self.next_size); - let layout = alloc::alloc::Layout::from_size_align(size as usize * BYTES_PER_WORD, - 8).unwrap(); + let layout = + alloc::alloc::Layout::from_size_align(size as usize * BYTES_PER_WORD, 8).unwrap(); let ptr = unsafe { alloc::alloc::alloc_zeroed(layout) }; - if ptr.is_null() { alloc::alloc::handle_alloc_error(layout); } + if ptr.is_null() { + alloc::alloc::handle_alloc_error(layout); + } match self.allocation_strategy { AllocationStrategy::GrowHeuristically => { if size < self.max_segment_words - self.next_size { @@ -612,15 +659,18 @@ unsafe impl Allocator for HeapAllocator { self.next_size = self.max_segment_words; } } - AllocationStrategy::FixedSize => { } + AllocationStrategy::FixedSize => {} } (ptr, size) } fn deallocate_segment(&mut self, ptr: *mut u8, word_size: u32, _words_used: u32) { unsafe { - alloc::alloc::dealloc(ptr, - alloc::alloc::Layout::from_size_align(word_size as usize * BYTES_PER_WORD, 8).unwrap()); + alloc::alloc::dealloc( + ptr, + alloc::alloc::Layout::from_size_align(word_size as usize * BYTES_PER_WORD, 8) + .unwrap(), + ); } self.next_size = SUGGESTED_FIRST_SEGMENT_WORDS; } @@ -633,9 +683,9 @@ fn test_allocate_max() { .max_segment_words((1 << 25) - 1) .first_segment_words(allocation_size); - let (a1,s1) = allocator.allocate_segment(allocation_size); - let (a2,s2) = allocator.allocate_segment(allocation_size); - let (a3,s3) = allocator.allocate_segment(allocation_size); + let (a1, s1) = allocator.allocate_segment(allocation_size); + let (a2, s2) = allocator.allocate_segment(allocation_size); + let (a3, s3) = allocator.allocate_segment(allocation_size); assert_eq!(s1, allocation_size); @@ -643,9 +693,9 @@ fn test_allocate_max() { assert_eq!(s2, allocator.max_segment_words); assert_eq!(s3, allocator.max_segment_words); - allocator.deallocate_segment(a1,s1,0); - allocator.deallocate_segment(a2,s2,0); - allocator.deallocate_segment(a3,s3,0); + allocator.deallocate_segment(a1, s1, 0); + allocator.deallocate_segment(a2, s2, 0); + allocator.deallocate_segment(a3, s3, 0); } impl Builder { @@ -672,7 +722,7 @@ pub struct ScratchSpaceHeapAllocator<'a> { allocator: HeapAllocator, } -impl <'a> ScratchSpaceHeapAllocator<'a> { +impl<'a> ScratchSpaceHeapAllocator<'a> { /// Writes zeroes into the entire buffer and constructs a new allocator from it. /// /// If the buffer is large, this operation could be relatively expensive. If you want to reuse @@ -682,8 +732,10 @@ impl <'a> ScratchSpaceHeapAllocator<'a> { #[cfg(not(feature = "unaligned"))] { if scratch_space.as_ptr() as usize % BYTES_PER_WORD != 0 { - panic!("Scratch space must be 8-byte aligned, or you must enable the \"unaligned\" \ - feature in the capnp crate"); + panic!( + "Scratch space must be 8-byte aligned, or you must enable the \"unaligned\" \ + feature in the capnp crate" + ); } } @@ -691,29 +743,41 @@ impl <'a> ScratchSpaceHeapAllocator<'a> { for b in &mut scratch_space[..] { *b = 0; } - ScratchSpaceHeapAllocator { scratch_space, - scratch_space_allocated: false, - allocator: HeapAllocator::new()} + ScratchSpaceHeapAllocator { + scratch_space, + scratch_space_allocated: false, + allocator: HeapAllocator::new(), + } } /// Sets the size of the second segment in words, where 1 word = 8 bytes. /// (The first segment is the scratch space passed to `ScratchSpaceHeapAllocator::new()`. pub fn second_segment_words(self, value: u32) -> ScratchSpaceHeapAllocator<'a> { - ScratchSpaceHeapAllocator { allocator: self.allocator.first_segment_words(value), ..self } - + ScratchSpaceHeapAllocator { + allocator: self.allocator.first_segment_words(value), + ..self + } } /// Sets the allocation strategy for segments after the second one. pub fn allocation_strategy(self, value: AllocationStrategy) -> ScratchSpaceHeapAllocator<'a> { - ScratchSpaceHeapAllocator { allocator: self.allocator.allocation_strategy(value), ..self } + ScratchSpaceHeapAllocator { + allocator: self.allocator.allocation_strategy(value), + ..self + } } } -unsafe impl <'a> Allocator for ScratchSpaceHeapAllocator<'a> { +unsafe impl<'a> Allocator for ScratchSpaceHeapAllocator<'a> { fn allocate_segment(&mut self, minimum_size: u32) -> (*mut u8, u32) { - if (minimum_size as usize) < (self.scratch_space.len() / BYTES_PER_WORD) && !self.scratch_space_allocated { + if (minimum_size as usize) < (self.scratch_space.len() / BYTES_PER_WORD) + && !self.scratch_space_allocated + { self.scratch_space_allocated = true; - (self.scratch_space.as_mut_ptr(), (self.scratch_space.len() / BYTES_PER_WORD) as u32) + ( + self.scratch_space.as_mut_ptr(), + (self.scratch_space.len() / BYTES_PER_WORD) as u32, + ) } else { self.allocator.allocate_segment(minimum_size) } @@ -728,12 +792,16 @@ unsafe impl <'a> Allocator for ScratchSpaceHeapAllocator<'a> { } self.scratch_space_allocated = false; } else { - self.allocator.deallocate_segment(ptr, word_size, words_used); + self.allocator + .deallocate_segment(ptr, word_size, words_used); } } } -unsafe impl <'a, A> Allocator for &'a mut A where A: Allocator { +unsafe impl<'a, A> Allocator for &'a mut A +where + A: Allocator, +{ fn allocate_segment(&mut self, minimum_size: u32) -> (*mut u8, u32) { (*self).allocate_segment(minimum_size) } @@ -742,4 +810,3 @@ unsafe impl <'a, A> Allocator for &'a mut A where A: Allocator { (*self).deallocate_segment(ptr, word_size, words_used) } } - diff --git a/capnp/src/primitive_list.rs b/capnp/src/primitive_list.rs index 96639e240..3d4c255fc 100644 --- a/capnp/src/primitive_list.rs +++ b/capnp/src/primitive_list.rs @@ -21,11 +21,12 @@ //! List of primitives. -use core::{marker}; +use core::marker; -use crate::traits::{FromPointerReader, FromPointerBuilder, IndexMove, ListIter}; -use crate::private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, - PrimitiveElement, data_bits_per_element}; +use crate::private::layout::{ + data_bits_per_element, ListBuilder, ListReader, PointerBuilder, PointerReader, PrimitiveElement, +}; +use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter}; use crate::Result; #[derive(Clone, Copy)] @@ -33,40 +34,53 @@ pub struct Owned { marker: marker::PhantomData, } -impl crate::traits::Owned for Owned where T: PrimitiveElement { +impl crate::traits::Owned for Owned +where + T: PrimitiveElement, +{ type Reader<'a> = Reader<'a, T>; type Builder<'a> = Builder<'a, T>; } #[derive(Clone, Copy)] -pub struct Reader<'a, T> where T: PrimitiveElement { +pub struct Reader<'a, T> +where + T: PrimitiveElement, +{ marker: marker::PhantomData, - reader: ListReader<'a> + reader: ListReader<'a>, } -impl <'a, T: PrimitiveElement> Reader<'a, T> { - pub fn len(&self) -> u32 { self.reader.len() } +impl<'a, T: PrimitiveElement> Reader<'a, T> { + pub fn len(&self) -> u32 { + self.reader.len() + } - pub fn iter(self) -> ListIter, T>{ + pub fn iter(self) -> ListIter, T> { let l = self.len(); ListIter::new(self, l) } } -impl <'a, T: PrimitiveElement> FromPointerReader<'a> for Reader<'a, T> { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader: reader.get_list(T::element_size(), default)?, - marker: marker::PhantomData }) +impl<'a, T: PrimitiveElement> FromPointerReader<'a> for Reader<'a, T> { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(T::element_size(), default)?, + marker: marker::PhantomData, + }) } } -impl <'a, T: PrimitiveElement> IndexMove for Reader<'a, T>{ +impl<'a, T: PrimitiveElement> IndexMove for Reader<'a, T> { fn index_move(&self, index: u32) -> T { self.get(index) } } -impl <'a, T: PrimitiveElement> Reader<'a, T> { +impl<'a, T: PrimitiveElement> Reader<'a, T> { /// Gets the `T` at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(&self, index: u32) -> T { @@ -89,9 +103,12 @@ impl <'a, T: PrimitiveElement> Reader<'a, T> { pub fn as_slice(&self) -> Option<&[T]> { if self.reader.get_element_size() == T::element_size() { let bytes = self.reader.into_raw_bytes(); - Some (unsafe { + Some(unsafe { use core::slice; - slice::from_raw_parts(bytes.as_ptr() as *mut T, 8*bytes.len()/(data_bits_per_element(T::element_size())) as usize) + slice::from_raw_parts( + bytes.as_ptr() as *mut T, + 8 * bytes.len() / (data_bits_per_element(T::element_size())) as usize, + ) }) } else { None @@ -99,19 +116,30 @@ impl <'a, T: PrimitiveElement> Reader<'a, T> { } } -impl <'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> where T: PrimitiveElement { +impl<'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> +where + T: PrimitiveElement, +{ fn into_internal_list_reader(self) -> ListReader<'a> { self.reader } } -pub struct Builder<'a, T> where T: PrimitiveElement { +pub struct Builder<'a, T> +where + T: PrimitiveElement, +{ marker: marker::PhantomData, - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a, T> Builder<'a, T> where T: PrimitiveElement { - pub fn len(&self) -> u32 { self.builder.len() } +impl<'a, T> Builder<'a, T> +where + T: PrimitiveElement, +{ + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn into_reader(self) -> Reader<'a, T> { Reader { @@ -128,9 +156,12 @@ impl <'a, T> Builder<'a, T> where T: PrimitiveElement { pub fn as_slice(&self) -> Option<&mut [T]> { if self.builder.get_element_size() == T::element_size() { let bytes = self.builder.into_raw_bytes(); - Some (unsafe { + Some(unsafe { use core::slice; - slice::from_raw_parts_mut(bytes.as_ptr() as *mut T, 8*bytes.len()/(data_bits_per_element(T::element_size())) as usize) + slice::from_raw_parts_mut( + bytes.as_ptr() as *mut T, + 8 * bytes.len() / (data_bits_per_element(T::element_size())) as usize, + ) }) } else { None @@ -138,18 +169,25 @@ impl <'a, T> Builder<'a, T> where T: PrimitiveElement { } } -impl <'a, T: PrimitiveElement> FromPointerBuilder<'a> for Builder<'a, T> { +impl<'a, T: PrimitiveElement> FromPointerBuilder<'a> for Builder<'a, T> { fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> { - Builder { builder: builder.init_list(T::element_size(), size), - marker: marker::PhantomData } + Builder { + builder: builder.init_list(T::element_size(), size), + marker: marker::PhantomData, + } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Builder { builder: builder.get_list(T::element_size(), default)?, - marker: marker::PhantomData }) + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Builder { + builder: builder.get_list(T::element_size(), default)?, + marker: marker::PhantomData, + }) } } -impl <'a, T : PrimitiveElement> Builder<'a, T> { +impl<'a, T: PrimitiveElement> Builder<'a, T> { /// Gets the `T` at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(&self, index: u32) -> T { @@ -168,22 +206,26 @@ impl <'a, T : PrimitiveElement> Builder<'a, T> { } pub fn reborrow(&self) -> Builder<'_, T> { - Builder { .. *self } + Builder { ..*self } } } -impl <'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> - where T: PrimitiveElement +impl<'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> +where + T: PrimitiveElement, { - fn set_pointer_builder<'b>(pointer: PointerBuilder<'b>, - value: Reader<'a, T>, - canonicalize: bool) -> Result<()> { + fn set_pointer_builder<'b>( + pointer: PointerBuilder<'b>, + value: Reader<'a, T>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize) } } -impl <'a, T> ::core::iter::IntoIterator for Reader<'a, T> - where T: PrimitiveElement +impl<'a, T> ::core::iter::IntoIterator for Reader<'a, T> +where + T: PrimitiveElement, { type Item = T; type IntoIter = ListIter, Self::Item>; diff --git a/capnp/src/private/arena.rs b/capnp/src/private/arena.rs index 19b52c291..427945b3c 100644 --- a/capnp/src/private/arena.rs +++ b/capnp/src/private/arena.rs @@ -24,10 +24,10 @@ use core::cell::RefCell; use core::slice; use core::u64; -use crate::private::units::*; -use crate::private::read_limiter::ReadLimiter; use crate::message; use crate::message::{Allocator, ReaderSegments}; +use crate::private::read_limiter::ReadLimiter; +use crate::private::units::*; use crate::{Error, OutputSegments, Result}; pub type SegmentId = u32; @@ -36,7 +36,12 @@ pub trait ReaderArena { // return pointer to start of segment, and number of words in that segment fn get_segment(&self, id: u32) -> Result<(*const u8, u32)>; - fn check_offset(&self, segment_id: u32, start: *const u8, offset_in_words: i32) -> Result<*const u8>; + fn check_offset( + &self, + segment_id: u32, + start: *const u8, + offset_in_words: i32, + ) -> Result<*const u8>; fn contains_interval(&self, segment_id: u32, start: *const u8, size: usize) -> Result<()>; fn amplified_read(&self, virtual_amount: u64) -> Result<()>; @@ -61,11 +66,11 @@ fn _assert_sync() { } } -impl ReaderArenaImpl where S: ReaderSegments { - pub fn new(segments: S, - options: message::ReaderOptions) - -> Self - { +impl ReaderArenaImpl +where + S: ReaderSegments, +{ + pub fn new(segments: S, options: message::ReaderOptions) -> Self { let limiter = ReadLimiter::new(options.traversal_limit_in_words); ReaderArenaImpl { segments, @@ -79,7 +84,10 @@ impl ReaderArenaImpl where S: ReaderSegments { } } -impl ReaderArena for ReaderArenaImpl where S: ReaderSegments { +impl ReaderArena for ReaderArenaImpl +where + S: ReaderSegments, +{ fn get_segment(&self, id: u32) -> Result<(*const u8, u32)> { match self.segments.get_segment(id) { Some(seg) => { @@ -89,7 +97,7 @@ impl ReaderArena for ReaderArenaImpl where S: ReaderSegments { return Err(Error::failed( String::from("Detected unaligned segment. You must either ensure all of your \ segments are 8-byte aligned, or you must enable the \"unaligned\" \ - feature in the capnp crate"))) + feature in the capnp crate"))); } } @@ -99,14 +107,22 @@ impl ReaderArena for ReaderArenaImpl where S: ReaderSegments { } } - fn check_offset(&self, segment_id: u32, start: *const u8, offset_in_words: i32) -> Result<*const u8> { + fn check_offset( + &self, + segment_id: u32, + start: *const u8, + offset_in_words: i32, + ) -> Result<*const u8> { let (segment_start, segment_len) = self.get_segment(segment_id)?; let this_start: usize = segment_start as usize; let this_size: usize = segment_len as usize * BYTES_PER_WORD; let offset: i64 = i64::from(offset_in_words) * BYTES_PER_WORD as i64; let start_idx = start as usize; - if start_idx < this_start || ((start_idx - this_start) as i64 + offset) as usize > this_size { - Err(Error::failed(String::from("message contained out-of-bounds pointer"))) + if start_idx < this_start || ((start_idx - this_start) as i64 + offset) as usize > this_size + { + Err(Error::failed(String::from( + "message contained out-of-bounds pointer", + ))) } else { unsafe { Ok(start.offset(offset as isize)) } } @@ -120,7 +136,9 @@ impl ReaderArena for ReaderArenaImpl where S: ReaderSegments { let size = size_in_words * BYTES_PER_WORD; if !(start >= this_start && start - this_start + size <= this_size) { - Err(Error::failed(String::from("message contained out-of-bounds pointer"))) + Err(Error::failed(String::from( + "message contained out-of-bounds pointer", + ))) } else { self.read_limiter.can_read(size_in_words) } @@ -130,7 +148,9 @@ impl ReaderArena for ReaderArenaImpl where S: ReaderSegments { self.read_limiter.can_read(virtual_amount as usize) } - fn nesting_limit(&self) -> i32 { self.nesting_limit } + fn nesting_limit(&self) -> i32 { + self.nesting_limit + } } pub trait BuilderArena: ReaderArena { @@ -149,22 +169,31 @@ pub trait BuilderArena: ReaderArena { struct BuilderSegment { ptr: *mut u8, - capacity: u32, // in words + capacity: u32, // in words allocated: u32, // in words } -pub struct BuilderArenaImplInner where A: Allocator { +pub struct BuilderArenaImplInner +where + A: Allocator, +{ allocator: Option, // None if has already be deallocated. // TODO(perf): Try using smallvec to avoid heap allocations in the single-segment case? segments: Vec, } -pub struct BuilderArenaImpl where A: Allocator { - inner: RefCell> +pub struct BuilderArenaImpl +where + A: Allocator, +{ + inner: RefCell>, } -impl BuilderArenaImpl where A: Allocator { +impl BuilderArenaImpl +where + A: Allocator, +{ pub fn new(allocator: A) -> Self { BuilderArenaImpl { inner: RefCell::new(BuilderArenaImplInner { @@ -187,13 +216,20 @@ impl BuilderArenaImpl where A: Allocator { // The user must mutably borrow the `message::Builder` to be able to modify segment memory. // No such borrow will be possible while `self` is still immutably borrowed from this method, // so returning this slice is safe. - let slice = unsafe { slice::from_raw_parts(seg.ptr as *const _, seg.allocated as usize * BYTES_PER_WORD) }; + let slice = unsafe { + slice::from_raw_parts(seg.ptr as *const _, seg.allocated as usize * BYTES_PER_WORD) + }; OutputSegments::SingleSegment([slice]) } else { let mut v = Vec::with_capacity(reff.segments.len()); for seg in &reff.segments { // See safety argument in above branch. - let slice = unsafe { slice::from_raw_parts(seg.ptr as *const _, seg.allocated as usize * BYTES_PER_WORD) }; + let slice = unsafe { + slice::from_raw_parts( + seg.ptr as *const _, + seg.allocated as usize * BYTES_PER_WORD, + ) + }; v.push(slice); } OutputSegments::MultiSegment(v) @@ -211,14 +247,22 @@ impl BuilderArenaImpl where A: Allocator { } } -impl ReaderArena for BuilderArenaImpl where A: Allocator { +impl ReaderArena for BuilderArenaImpl +where + A: Allocator, +{ fn get_segment(&self, id: u32) -> Result<(*const u8, u32)> { let borrow = self.inner.borrow(); let seg = &borrow.segments[id as usize]; Ok((seg.ptr, seg.allocated)) } - fn check_offset(&self, _segment_id: u32, start: *const u8, offset_in_words: i32) -> Result<*const u8> { + fn check_offset( + &self, + _segment_id: u32, + start: *const u8, + offset_in_words: i32, + ) -> Result<*const u8> { unsafe { Ok(start.offset((i64::from(offset_in_words) * BYTES_PER_WORD as i64) as isize)) } } @@ -230,17 +274,26 @@ impl ReaderArena for BuilderArenaImpl where A: Allocator { Ok(()) } - fn nesting_limit(&self) -> i32 { 0x7fffffff } + fn nesting_limit(&self) -> i32 { + 0x7fffffff + } } -impl BuilderArenaImplInner where A: Allocator { +impl BuilderArenaImplInner +where + A: Allocator, +{ /// Allocates a new segment with capacity for at least `minimum_size` words. fn allocate_segment(&mut self, minimum_size: WordCount32) -> Result<()> { let seg = match self.allocator { Some(ref mut a) => a.allocate_segment(minimum_size), None => unreachable!(), }; - self.segments.push(BuilderSegment { ptr: seg.0, capacity: seg.1, allocated: 0}); + self.segments.push(BuilderSegment { + ptr: seg.0, + capacity: seg.1, + allocated: 0, + }); Ok(()) } @@ -258,7 +311,7 @@ impl BuilderArenaImplInner where A: Allocator { fn allocate_anywhere(&mut self, amount: u32) -> (SegmentId, u32) { // first try the existing segments, then try allocating a new segment. let allocated_len = self.segments.len() as u32; - for segment_id in 0.. allocated_len { + for segment_id in 0..allocated_len { if let Some(idx) = self.allocate(segment_id, amount) { return (segment_id, idx); } @@ -267,8 +320,11 @@ impl BuilderArenaImplInner where A: Allocator { // Need to allocate a new segment. self.allocate_segment(amount).expect("allocate new segment"); - (allocated_len, - self.allocate(allocated_len, amount).expect("use freshly-allocated segment")) + ( + allocated_len, + self.allocate(allocated_len, amount) + .expect("use freshly-allocated segment"), + ) } fn deallocate_all(&mut self) { @@ -285,7 +341,10 @@ impl BuilderArenaImplInner where A: Allocator { } } -impl BuilderArena for BuilderArenaImpl where A: Allocator { +impl BuilderArena for BuilderArenaImpl +where + A: Allocator, +{ fn allocate(&self, segment_id: u32, amount: WordCount32) -> Option { self.inner.borrow_mut().allocate(segment_id, amount) } @@ -303,7 +362,10 @@ impl BuilderArena for BuilderArenaImpl where A: Allocator { } } -impl Drop for BuilderArenaImplInner where A: Allocator { +impl Drop for BuilderArenaImplInner +where + A: Allocator, +{ fn drop(&mut self) { self.deallocate_all() } @@ -316,7 +378,12 @@ impl ReaderArena for NullArena { Err(Error::failed(String::from("tried to read from null arena"))) } - fn check_offset(&self, _segment_id: u32, start: *const u8, offset_in_words: i32) -> Result<*const u8> { + fn check_offset( + &self, + _segment_id: u32, + start: *const u8, + offset_in_words: i32, + ) -> Result<*const u8> { unsafe { Ok(start.add(offset_in_words as usize * BYTES_PER_WORD)) } } @@ -328,7 +395,9 @@ impl ReaderArena for NullArena { Ok(()) } - fn nesting_limit(&self) -> i32 { 0x7fffffff } + fn nesting_limit(&self) -> i32 { + 0x7fffffff + } } impl BuilderArena for NullArena { @@ -348,4 +417,3 @@ impl BuilderArena for NullArena { self } } - diff --git a/capnp/src/private/capability.rs b/capnp/src/private/capability.rs index 86f22cd4c..fc7c8be32 100644 --- a/capnp/src/private/capability.rs +++ b/capnp/src/private/capability.rs @@ -23,8 +23,8 @@ use alloc::boxed::Box; use alloc::vec::Vec; use crate::any_pointer; +use crate::capability::{Params, Promise, RemotePromise, Request, Results}; use crate::MessageSize; -use crate::capability::{Params, Promise, Request, RemotePromise, Results}; pub trait ResponseHook { fn get(&self) -> crate::Result>; @@ -34,21 +34,31 @@ pub trait RequestHook { fn get(&mut self) -> any_pointer::Builder<'_>; fn get_brand(&self) -> usize; fn send(self: Box) -> RemotePromise; - fn tail_send(self: Box) - -> Option<(u32, crate::capability::Promise<(), crate::Error>, Box)>; + fn tail_send( + self: Box, + ) -> Option<( + u32, + crate::capability::Promise<(), crate::Error>, + Box, + )>; } pub trait ClientHook { fn add_ref(&self) -> Box; - fn new_call(&self, - interface_id: u64, - method_id: u16, - size_hint: Option) - -> Request; - - fn call(&self, interface_id: u64, method_id: u16, - params: Box, results: Box) - -> crate::capability::Promise<(), crate::Error>; + fn new_call( + &self, + interface_id: u64, + method_id: u16, + size_hint: Option, + ) -> Request; + + fn call( + &self, + interface_id: u64, + method_id: u16, + params: Box, + results: Box, + ) -> crate::capability::Promise<(), crate::Error>; /// If this capability is associated with an rpc connection, then this method /// returns an identifier for that connection. @@ -63,12 +73,13 @@ pub trait ClientHook { /// `whenMoreResolved()` to distinguish between them. fn get_resolved(&self) -> Option>; - /// If this client is a settled reference (not a promise), return nullptr. Otherwise, return a /// promise that eventually resolves to a new client that is closer to being the final, settled /// client (i.e. the value eventually returned by `getResolved()`). Calling this repeatedly /// should eventually produce a settled client. - fn when_more_resolved(&self) -> Option, crate::Error>>; + fn when_more_resolved( + &self, + ) -> Option, crate::Error>>; /// Repeatedly calls whenMoreResolved() until it returns nullptr. fn when_resolved(&self) -> Promise<(), crate::Error>; @@ -84,8 +95,13 @@ pub trait ResultsHook { fn get(&mut self) -> crate::Result>; fn allow_cancellation(&self); fn tail_call(self: Box, request: Box) -> Promise<(), crate::Error>; - fn direct_tail_call(self: Box, request: Box) -> - (crate::capability::Promise<(), crate::Error>, Box); + fn direct_tail_call( + self: Box, + request: Box, + ) -> ( + crate::capability::Promise<(), crate::Error>, + Box, + ); } pub trait ParamsHook { @@ -94,15 +110,24 @@ pub trait ParamsHook { // Where should this live? pub fn internal_get_typed_params(typeless: Params) -> Params { - Params { hook: typeless.hook, marker: ::core::marker::PhantomData } + Params { + hook: typeless.hook, + marker: ::core::marker::PhantomData, + } } pub fn internal_get_typed_results(typeless: Results) -> Results { - Results { hook: typeless.hook, marker: ::core::marker::PhantomData } + Results { + hook: typeless.hook, + marker: ::core::marker::PhantomData, + } } pub fn internal_get_untyped_results(typeful: Results) -> Results { - Results { hook: typeful.hook, marker: ::core::marker::PhantomData } + Results { + hook: typeful.hook, + marker: ::core::marker::PhantomData, + } } pub trait PipelineHook { diff --git a/capnp/src/private/layout.rs b/capnp/src/private/layout.rs index cb009dfa9..76170bd5e 100644 --- a/capnp/src/private/layout.rs +++ b/capnp/src/private/layout.rs @@ -22,21 +22,23 @@ use alloc::boxed::Box; use alloc::string::String; use alloc::vec::Vec; +use core::cell::Cell; use core::mem; use core::ptr; -use core::cell::Cell; use crate::data; -use crate::text; -use crate::private::capability::{ClientHook}; -use crate::private::arena::{BuilderArena, ReaderArena, NullArena, SegmentId}; +use crate::private::arena::{BuilderArena, NullArena, ReaderArena, SegmentId}; +use crate::private::capability::ClientHook; use crate::private::mask::Mask; use crate::private::primitive::{Primitive, WireValue}; use crate::private::units::*; use crate::private::zero; +use crate::text; use crate::{MessageSize, Result}; -pub use self::ElementSize::{Void, Bit, Byte, TwoBytes, FourBytes, EightBytes, Pointer, InlineComposite}; +pub use self::ElementSize::{ + Bit, Byte, EightBytes, FourBytes, InlineComposite, Pointer, TwoBytes, Void, +}; #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq)] @@ -48,7 +50,7 @@ pub enum ElementSize { FourBytes = 4, EightBytes = 5, Pointer = 6, - InlineComposite = 7 + InlineComposite = 7, } impl ElementSize { @@ -76,14 +78,14 @@ pub fn data_bits_per_element(size: ElementSize) -> BitCount32 { FourBytes => 32, EightBytes => 64, Pointer => 0, - InlineComposite => 0 + InlineComposite => 0, } } pub fn pointers_per_element(size: ElementSize) -> WirePointerCount32 { match size { Pointer => 1, - _ => 0 + _ => 0, } } @@ -95,9 +97,7 @@ pub struct StructSize { impl StructSize { pub fn total(&self) -> WordCount32 { - u32::from(self.data) - + u32::from(self.pointers) - * WORDS_PER_POINTER as WordCount32 + u32::from(self.data) + u32::from(self.pointers) * WORDS_PER_POINTER as WordCount32 } } @@ -107,7 +107,7 @@ pub enum WirePointerKind { Struct = 0, List = 1, Far = 2, - Other = 3 + Other = 3, } pub enum PointerType { @@ -143,7 +143,6 @@ fn wire_pointer_align() { } impl WirePointer { - #[inline] pub fn kind(&self) -> WirePointerKind { WirePointerKind::from(self.offset_and_kind.get() as u8 & 3) @@ -166,7 +165,11 @@ impl WirePointer { } #[inline] - pub fn target_from_segment(&self, arena: &dyn ReaderArena, segment_id: u32) -> Result<*const u8> { + pub fn target_from_segment( + &self, + arena: &dyn ReaderArena, + segment_id: u32, + ) -> Result<*const u8> { let this_addr: *const u8 = self as *const _ as *const _; let offset = 1 + ((self.offset_and_kind.get() as i32) >> 2); arena.check_offset(segment_id, this_addr, offset) @@ -175,7 +178,9 @@ impl WirePointer { #[inline] pub fn mut_target(&mut self) -> *mut u8 { let this_addr: *mut u8 = self as *mut _ as *mut _; - this_addr.wrapping_offset(BYTES_PER_WORD as isize * (1 + ((self.offset_and_kind.get() as i32) >> 2)) as isize) + this_addr.wrapping_offset( + BYTES_PER_WORD as isize * (1 + ((self.offset_and_kind.get() as i32) >> 2)) as isize, + ) } #[inline] @@ -184,7 +189,8 @@ impl WirePointer { let target_addr: isize = target as *const _ as isize; self.offset_and_kind.set( ((((target_addr - this_addr) / BYTES_PER_WORD as isize) as i32 - 1) << 2) as u32 - | (kind as u32)) + | (kind as u32), + ) } #[inline] @@ -212,10 +218,13 @@ impl WirePointer { } #[inline] - pub fn set_kind_and_inline_composite_list_element_count(&mut self, - kind: WirePointerKind, - element_count: ElementCount32) { - self.offset_and_kind.set(( element_count << 2) | (kind as u32)) + pub fn set_kind_and_inline_composite_list_element_count( + &mut self, + kind: WirePointerKind, + element_count: ElementCount32, + ) { + self.offset_and_kind + .set((element_count << 2) | (kind as u32)) } #[inline] @@ -231,7 +240,7 @@ impl WirePointer { #[inline] pub fn set_far(&mut self, is_double_far: bool, pos: WordCount32) { self.offset_and_kind - .set(( pos << 3) | (u32::from(is_double_far) << 2) | WirePointerKind::Far as u32); + .set((pos << 3) | (u32::from(is_double_far) << 2) | WirePointerKind::Far as u32); } #[inline] @@ -252,18 +261,22 @@ impl WirePointer { #[inline] pub fn struct_word_size(&self) -> WordCount32 { - u32::from(self.struct_data_size()) + - u32::from(self.struct_ptr_count()) * WORDS_PER_POINTER as u32 + u32::from(self.struct_data_size()) + + u32::from(self.struct_ptr_count()) * WORDS_PER_POINTER as u32 } #[inline] pub fn set_struct_size(&mut self, size: StructSize) { - self.upper32bits.set(u32::from(size.data) | (u32::from(size.pointers) << 16)) + self.upper32bits + .set(u32::from(size.data) | (u32::from(size.pointers) << 16)) } #[inline] pub fn set_struct_size_from_pieces(&mut self, ds: WordCount16, rc: WirePointerCount16) { - self.set_struct_size(StructSize { data: ds, pointers: rc }) + self.set_struct_size(StructSize { + data: ds, + pointers: rc, + }) } #[inline] @@ -284,12 +297,15 @@ impl WirePointer { #[inline] pub fn set_list_size_and_count(&mut self, es: ElementSize, ec: ElementCount32) { assert!(ec < (1 << 29), "Lists are limited to 2**29 elements"); - self.upper32bits.set((ec << 3 ) | (es as u32)); + self.upper32bits.set((ec << 3) | (es as u32)); } #[inline] pub fn set_list_inline_composite(&mut self, wc: WordCount32) { - assert!(wc < (1 << 29), "Inline composite lists are limited to 2**29 words"); + assert!( + wc < (1 << 29), + "Inline composite lists are limited to 2**29 words" + ); self.upper32bits.set((wc << 3) | (InlineComposite as u32)); } @@ -324,15 +340,16 @@ mod wire_helpers { use alloc::string::ToString; use core::{ptr, slice}; - use crate::private::capability::ClientHook; + use crate::data; use crate::private::arena::*; - use crate::private::layout::{ - CapTableBuilder, CapTableReader, ElementSize, ListBuilder, ListReader, - StructBuilder, StructReader, StructSize, WirePointer, WirePointerKind}; - use crate::private::layout::{data_bits_per_element, pointers_per_element}; + use crate::private::capability::ClientHook; use crate::private::layout::ElementSize::*; + use crate::private::layout::{data_bits_per_element, pointers_per_element}; + use crate::private::layout::{ + CapTableBuilder, CapTableReader, ElementSize, ListBuilder, ListReader, StructBuilder, + StructReader, StructSize, WirePointer, WirePointerKind, + }; use crate::private::units::*; - use crate::data; use crate::text; use crate::{Error, MessageSize, Result}; @@ -365,16 +382,18 @@ mod wire_helpers { } #[inline] - pub fn bounds_check(arena: &dyn ReaderArena, - segment_id: u32, - start: *const u8, size_in_words: usize, - _kind: WirePointerKind) -> Result<()> { + pub fn bounds_check( + arena: &dyn ReaderArena, + segment_id: u32, + start: *const u8, + size_in_words: usize, + _kind: WirePointerKind, + ) -> Result<()> { arena.contains_interval(segment_id, start, size_in_words) } #[inline] - pub fn amplified_read(arena: &dyn ReaderArena, - virtual_amount: u64) -> Result<()> { + pub fn amplified_read(arena: &dyn ReaderArena, virtual_amount: u64) -> Result<()> { arena.amplified_read(virtual_amount) } @@ -383,8 +402,9 @@ mod wire_helpers { arena: &dyn BuilderArena, reff: *mut WirePointer, segment_id: u32, - amount: WordCount32, kind: WirePointerKind) -> (*mut u8, *mut WirePointer, u32) - { + amount: WordCount32, + kind: WirePointerKind, + ) -> (*mut u8, *mut WirePointer, u32) { let is_null = (*reff).is_null(); if !is_null { zero_object(arena, segment_id, reff) @@ -397,7 +417,6 @@ mod wire_helpers { match arena.allocate(segment_id, amount) { None => { - //# Need to allocate in a different segment. We'll need to //# allocate an extra pointer worth of space to act as //# the landing pad for a far pointer. @@ -434,8 +453,8 @@ mod wire_helpers { arena: &dyn BuilderArena, reff: *mut WirePointer, ref_target: *mut u8, - segment_id: u32) -> Result<(*mut u8, *mut WirePointer, u32)> - { + segment_id: u32, + ) -> Result<(*mut u8, *mut WirePointer, u32)> { // If `ref` is a far pointer, follow it. On return, `ref` will have been updated to point at // a WirePointer that contains the type information about the target object, and a pointer // to the object contents is returned. The caller must NOT use `ref->target()` as this may @@ -459,7 +478,8 @@ mod wire_helpers { let segment_id = (*pad).far_segment_id(); let (segment_start, _segment_len) = arena.get_segment_mut(segment_id); - let ptr = segment_start.offset((*pad).far_position_in_segment() as isize * BYTES_PER_WORD as isize); + let ptr = segment_start + .offset((*pad).far_position_in_segment() as isize * BYTES_PER_WORD as isize); Ok((ptr, reff, segment_id)) } } else { @@ -475,14 +495,14 @@ mod wire_helpers { pub unsafe fn follow_fars( arena: &dyn ReaderArena, reff: *const WirePointer, - segment_id: u32) - -> Result<(*const u8, *const WirePointer, u32)> - { + segment_id: u32, + ) -> Result<(*const u8, *const WirePointer, u32)> { if (*reff).kind() == WirePointerKind::Far { let far_segment_id = (*reff).far_segment_id(); let (seg_start, _seg_len) = arena.get_segment(far_segment_id)?; - let ptr = seg_start.offset((*reff).far_position_in_segment() as isize * BYTES_PER_WORD as isize); + let ptr = seg_start + .offset((*reff).far_position_in_segment() as isize * BYTES_PER_WORD as isize); let pad_words: usize = if (*reff).is_double_far() { 2 } else { 1 }; bounds_check(arena, far_segment_id, ptr, pad_words, WirePointerKind::Far)?; @@ -490,7 +510,11 @@ mod wire_helpers { let pad: *const WirePointer = ptr as *const _; if !(*reff).is_double_far() { - Ok(((*pad).target_from_segment(arena, far_segment_id)?, pad, far_segment_id)) + Ok(( + (*pad).target_from_segment(arena, far_segment_id)?, + pad, + far_segment_id, + )) } else { // Landing pad is another far pointer. It is followed by a tag describing the // pointed-to object. @@ -498,19 +522,20 @@ mod wire_helpers { let tag = pad.offset(1); let double_far_segment_id = (*pad).far_segment_id(); let (segment_start, _segment_len) = arena.get_segment(double_far_segment_id)?; - let ptr = segment_start.offset((*pad).far_position_in_segment() as isize * BYTES_PER_WORD as isize); + let ptr = segment_start + .offset((*pad).far_position_in_segment() as isize * BYTES_PER_WORD as isize); Ok((ptr, tag, double_far_segment_id)) } } else { - Ok(((*reff).target_from_segment(arena, segment_id)?, reff, segment_id)) + Ok(( + (*reff).target_from_segment(arena, segment_id)?, + reff, + segment_id, + )) } } - pub unsafe fn zero_object( - arena: &dyn BuilderArena, - segment_id: u32, - reff: *mut WirePointer) - { + pub unsafe fn zero_object(arena: &dyn BuilderArena, segment_id: u32, reff: *mut WirePointer) { //# Zero out the pointed-to object. Use when the pointer is //# about to be overwritten making the target object no longer //# reachable. @@ -522,21 +547,19 @@ mod wire_helpers { WirePointerKind::Far => { let segment_id = (*reff).far_segment_id(); let (seg_start, _seg_len) = arena.get_segment_mut(segment_id); - let pad: *mut WirePointer = - (seg_start as *mut WirePointer).offset((*reff).far_position_in_segment() as isize); + let pad: *mut WirePointer = (seg_start as *mut WirePointer) + .offset((*reff).far_position_in_segment() as isize); if (*reff).is_double_far() { let segment_id = (*pad).far_segment_id(); let (seg_start, _seg_len) = arena.get_segment_mut(segment_id); - let ptr = seg_start.offset((*pad).far_position_in_segment() as isize * BYTES_PER_WORD as isize); - zero_object_helper(arena, - segment_id, - pad.offset(1), - ptr); + let ptr = seg_start.offset( + (*pad).far_position_in_segment() as isize * BYTES_PER_WORD as isize, + ); + zero_object_helper(arena, segment_id, pad.offset(1), ptr); ptr::write_bytes(pad, 0u8, 2); - } else { zero_object(arena, segment_id, pad); ptr::write_bytes(pad, 0u8, 1); @@ -549,65 +572,80 @@ mod wire_helpers { arena: &dyn BuilderArena, segment_id: u32, tag: *mut WirePointer, - ptr: *mut u8) - { + ptr: *mut u8, + ) { match (*tag).kind() { - WirePointerKind::Other => { panic!("Don't know how to handle OTHER") } + WirePointerKind::Other => { + panic!("Don't know how to handle OTHER") + } WirePointerKind::Struct => { - let pointer_section: *mut WirePointer = - ptr.offset((*tag).struct_data_size() as isize * BYTES_PER_WORD as isize) as *mut _; + let pointer_section: *mut WirePointer = ptr + .offset((*tag).struct_data_size() as isize * BYTES_PER_WORD as isize) + as *mut _; let count = (*tag).struct_ptr_count() as isize; for i in 0..count { zero_object(arena, segment_id, pointer_section.offset(i)); } - ptr::write_bytes(ptr, 0u8, (*tag).struct_word_size() as usize * BYTES_PER_WORD); + ptr::write_bytes( + ptr, + 0u8, + (*tag).struct_word_size() as usize * BYTES_PER_WORD, + ); } - WirePointerKind::List => { - match (*tag).list_element_size() { - Void => { } - Bit | Byte | TwoBytes | FourBytes | EightBytes => { - ptr::write_bytes( - ptr, 0u8, - BYTES_PER_WORD * - round_bits_up_to_words( - u64::from((*tag).list_element_count()) * - u64::from(data_bits_per_element( - (*tag).list_element_size()))) as usize) - } - Pointer => { - let count = (*tag).list_element_count() as usize; - for i in 0..count as isize { - zero_object(arena, segment_id, ptr.offset(i * BYTES_PER_WORD as isize) as *mut _); - } - ptr::write_bytes(ptr, 0u8, count * BYTES_PER_WORD); + WirePointerKind::List => match (*tag).list_element_size() { + Void => {} + Bit | Byte | TwoBytes | FourBytes | EightBytes => ptr::write_bytes( + ptr, + 0u8, + BYTES_PER_WORD + * round_bits_up_to_words( + u64::from((*tag).list_element_count()) + * u64::from(data_bits_per_element((*tag).list_element_size())), + ) as usize, + ), + Pointer => { + let count = (*tag).list_element_count() as usize; + for i in 0..count as isize { + zero_object( + arena, + segment_id, + ptr.offset(i * BYTES_PER_WORD as isize) as *mut _, + ); } - InlineComposite => { - let element_tag: *mut WirePointer = ptr as *mut _; - - assert!((*element_tag).kind() == WirePointerKind::Struct, - "Don't know how to handle non-STRUCT inline composite"); - - let data_size = (*element_tag).struct_data_size(); - let pointer_count = (*element_tag).struct_ptr_count(); - let mut pos = ptr.add(BYTES_PER_WORD); - let count = (*element_tag).inline_composite_list_element_count(); - if pointer_count > 0 { - for _ in 0..count { - pos = pos.offset(data_size as isize * BYTES_PER_WORD as isize); - for _ in 0..pointer_count { - zero_object(arena, segment_id, pos as *mut WirePointer); - pos = pos.add(BYTES_PER_WORD); - } + ptr::write_bytes(ptr, 0u8, count * BYTES_PER_WORD); + } + InlineComposite => { + let element_tag: *mut WirePointer = ptr as *mut _; + + assert!( + (*element_tag).kind() == WirePointerKind::Struct, + "Don't know how to handle non-STRUCT inline composite" + ); + + let data_size = (*element_tag).struct_data_size(); + let pointer_count = (*element_tag).struct_ptr_count(); + let mut pos = ptr.add(BYTES_PER_WORD); + let count = (*element_tag).inline_composite_list_element_count(); + if pointer_count > 0 { + for _ in 0..count { + pos = pos.offset(data_size as isize * BYTES_PER_WORD as isize); + for _ in 0..pointer_count { + zero_object(arena, segment_id, pos as *mut WirePointer); + pos = pos.add(BYTES_PER_WORD); } } - ptr::write_bytes(ptr, 0u8, - BYTES_PER_WORD * - ((*element_tag).struct_word_size() * count + 1) as usize); } + ptr::write_bytes( + ptr, + 0u8, + BYTES_PER_WORD * ((*element_tag).struct_word_size() * count + 1) as usize, + ); } + }, + WirePointerKind::Far => { + panic!("Unexpected FAR pointer") } - WirePointerKind::Far => { panic!("Unexpected FAR pointer") } } } @@ -615,15 +653,16 @@ mod wire_helpers { pub unsafe fn zero_pointer_and_fars( arena: &dyn BuilderArena, _segment_id: u32, - reff: *mut WirePointer) -> Result<()> - { + reff: *mut WirePointer, + ) -> Result<()> { // Zero out the pointer itself and, if it is a far pointer, zero the landing pad as well, // but do not zero the object body. Used when upgrading. if (*reff).kind() == WirePointerKind::Far { let far_segment_id = (*reff).far_segment_id(); let (seg_start, _seg_len) = arena.get_segment_mut(far_segment_id); - let pad = seg_start.offset((*reff).far_position_in_segment() as isize * BYTES_PER_WORD as isize); + let pad = seg_start + .offset((*reff).far_position_in_segment() as isize * BYTES_PER_WORD as isize); let num_elements = if (*reff).is_double_far() { 2 } else { 1 }; ptr::write_bytes(pad, 0, num_elements * BYTES_PER_WORD); } @@ -635,11 +674,16 @@ mod wire_helpers { arena: &dyn ReaderArena, segment_id: u32, reff: *const WirePointer, - mut nesting_limit: i32) -> Result - { - let mut result = MessageSize { word_count: 0, cap_count: 0}; + mut nesting_limit: i32, + ) -> Result { + let mut result = MessageSize { + word_count: 0, + cap_count: 0, + }; - if (*reff).is_null() { return Ok(result) }; + if (*reff).is_null() { + return Ok(result); + }; if nesting_limit <= 0 { return Err(Error::failed("Message is too deeply nested.".to_string())); @@ -651,16 +695,22 @@ mod wire_helpers { match (*reff).kind() { WirePointerKind::Struct => { - bounds_check(arena, segment_id, - ptr, (*reff).struct_word_size() as usize, - WirePointerKind::Struct)?; + bounds_check( + arena, + segment_id, + ptr, + (*reff).struct_word_size() as usize, + WirePointerKind::Struct, + )?; result.word_count += u64::from((*reff).struct_word_size()); - let pointer_section: *const WirePointer = - ptr.offset((*reff).struct_data_size() as isize * BYTES_PER_WORD as isize) as *const _; + let pointer_section: *const WirePointer = ptr + .offset((*reff).struct_data_size() as isize * BYTES_PER_WORD as isize) + as *const _; let count: isize = (*reff).struct_ptr_count() as isize; for i in 0..count { - result += total_size(arena, segment_id, pointer_section.offset(i), nesting_limit)?; + result += + total_size(arena, segment_id, pointer_section.offset(i), nesting_limit)?; } } WirePointerKind::List => { @@ -668,45 +718,65 @@ mod wire_helpers { Void => {} Bit | Byte | TwoBytes | FourBytes | EightBytes => { let total_words = round_bits_up_to_words( - u64::from((*reff).list_element_count()) * - u64::from(data_bits_per_element((*reff).list_element_size()))); + u64::from((*reff).list_element_count()) + * u64::from(data_bits_per_element((*reff).list_element_size())), + ); bounds_check( - arena, segment_id, ptr, total_words as usize, WirePointerKind::List)?; + arena, + segment_id, + ptr, + total_words as usize, + WirePointerKind::List, + )?; result.word_count += u64::from(total_words); } Pointer => { let count = (*reff).list_element_count(); bounds_check( - arena, segment_id, ptr, count as usize * WORDS_PER_POINTER, - WirePointerKind::List)?; + arena, + segment_id, + ptr, + count as usize * WORDS_PER_POINTER, + WirePointerKind::List, + )?; result.word_count += u64::from(count) * WORDS_PER_POINTER as u64; for i in 0..count as isize { - result += - total_size(arena, segment_id, - (ptr as *const WirePointer).offset(i), - nesting_limit)?; + result += total_size( + arena, + segment_id, + (ptr as *const WirePointer).offset(i), + nesting_limit, + )?; } } InlineComposite => { let word_count = (*reff).list_inline_composite_word_count(); - bounds_check(arena, segment_id, ptr, - word_count as usize + POINTER_SIZE_IN_WORDS, - WirePointerKind::List)?; + bounds_check( + arena, + segment_id, + ptr, + word_count as usize + POINTER_SIZE_IN_WORDS, + WirePointerKind::List, + )?; let element_tag: *const WirePointer = ptr as *const _; let count = (*element_tag).inline_composite_list_element_count(); if (*element_tag).kind() != WirePointerKind::Struct { return Err(Error::failed( - "Don't know how to handle non-STRUCT inline composite.".to_string())); + "Don't know how to handle non-STRUCT inline composite.".to_string(), + )); } - let actual_size = u64::from((*element_tag).struct_word_size()) * u64::from(count); + let actual_size = + u64::from((*element_tag).struct_word_size()) * u64::from(count); if actual_size > u64::from(word_count) { return Err(Error::failed( - "InlineComposite list's elements overrun its word count.".to_string())); + "InlineComposite list's elements overrun its word count." + .to_string(), + )); } // Count the actual size rather than the claimed word count because @@ -722,9 +792,12 @@ mod wire_helpers { pos = pos.offset(data_size as isize * BYTES_PER_WORD as isize); for _ in 0..pointer_count { - result += - total_size(arena, segment_id, - pos as *const WirePointer, nesting_limit)?; + result += total_size( + arena, + segment_id, + pos as *const WirePointer, + nesting_limit, + )?; pos = pos.add(BYTES_PER_WORD); } } @@ -755,14 +828,21 @@ mod wire_helpers { dst: *mut u8, src: *const u8, data_size: isize, - pointer_count: isize) { + pointer_count: isize, + ) { ptr::copy_nonoverlapping(src, dst, data_size as usize * BYTES_PER_WORD); let src_refs: *const WirePointer = (src as *const WirePointer).offset(data_size); let dst_refs: *mut WirePointer = (dst as *mut WirePointer).offset(data_size); for ii in 0..pointer_count { - copy_message(arena, segment_id, cap_table, dst_refs.offset(ii), src_refs.offset(ii)); + copy_message( + arena, + segment_id, + cap_table, + dst_refs.offset(ii), + src_refs.offset(ii), + ); } } @@ -773,8 +853,8 @@ mod wire_helpers { segment_id: u32, cap_table: CapTableBuilder, dst: *mut WirePointer, - src: *const WirePointer) -> (*mut u8, *mut WirePointer, u32) - { + src: *const WirePointer, + ) -> (*mut u8, *mut WirePointer, u32) { match (*src).kind() { WirePointerKind::Struct => { if (*src).is_null() { @@ -783,89 +863,117 @@ mod wire_helpers { } else { let src_ptr = (*src).target(); let (dst_ptr, dst, segment_id) = allocate( - arena, dst, segment_id, (*src).struct_word_size(), WirePointerKind::Struct); - copy_struct(arena, - segment_id, - cap_table, - dst_ptr, - src_ptr, - (*src).struct_data_size() as isize, - (*src).struct_ptr_count() as isize); - (*dst).set_struct_size_from_pieces((*src).struct_data_size(), (*src).struct_ptr_count()); + arena, + dst, + segment_id, + (*src).struct_word_size(), + WirePointerKind::Struct, + ); + copy_struct( + arena, + segment_id, + cap_table, + dst_ptr, + src_ptr, + (*src).struct_data_size() as isize, + (*src).struct_ptr_count() as isize, + ); + (*dst).set_struct_size_from_pieces( + (*src).struct_data_size(), + (*src).struct_ptr_count(), + ); (dst_ptr, dst, segment_id) } } - WirePointerKind::List => { - match (*src).list_element_size() { - ElementSize::Void | - ElementSize::Bit | - ElementSize::Byte | - ElementSize::TwoBytes | - ElementSize::FourBytes | - ElementSize::EightBytes => { - let word_count = round_bits_up_to_words( - u64::from((*src).list_element_count()) * - u64::from(data_bits_per_element((*src).list_element_size()))); - let src_ptr = (*src).target(); - let (dst_ptr, dst, segment_id) = allocate( - arena, dst, segment_id, word_count, WirePointerKind::List); - ptr::copy_nonoverlapping(src_ptr, dst_ptr, word_count as usize * BYTES_PER_WORD); - (*dst).set_list_size_and_count((*src).list_element_size(), - (*src).list_element_count()); - (dst_ptr, dst, segment_id) - } + WirePointerKind::List => match (*src).list_element_size() { + ElementSize::Void + | ElementSize::Bit + | ElementSize::Byte + | ElementSize::TwoBytes + | ElementSize::FourBytes + | ElementSize::EightBytes => { + let word_count = round_bits_up_to_words( + u64::from((*src).list_element_count()) + * u64::from(data_bits_per_element((*src).list_element_size())), + ); + let src_ptr = (*src).target(); + let (dst_ptr, dst, segment_id) = + allocate(arena, dst, segment_id, word_count, WirePointerKind::List); + ptr::copy_nonoverlapping( + src_ptr, + dst_ptr, + word_count as usize * BYTES_PER_WORD, + ); + (*dst).set_list_size_and_count( + (*src).list_element_size(), + (*src).list_element_count(), + ); + (dst_ptr, dst, segment_id) + } - ElementSize::Pointer => { - let src_refs: *const WirePointer = (*src).target() as _; - let (dst_refs, dst, segment_id) = allocate( - arena, dst, segment_id, - (*src).list_element_count(), - WirePointerKind::List); - for ii in 0 .. ((*src).list_element_count() as isize) { - copy_message(arena, - segment_id, - cap_table, - dst_refs.offset(ii * BYTES_PER_WORD as isize) as *mut WirePointer, - src_refs.offset(ii)); - } - (*dst).set_list_size_and_count(ElementSize::Pointer, (*src).list_element_count()); - (dst_refs, dst, segment_id) - } - ElementSize::InlineComposite => { - let src_ptr = (*src).target(); - let (dst_ptr, dst, segment_id) = allocate( + ElementSize::Pointer => { + let src_refs: *const WirePointer = (*src).target() as _; + let (dst_refs, dst, segment_id) = allocate( + arena, + dst, + segment_id, + (*src).list_element_count(), + WirePointerKind::List, + ); + for ii in 0..((*src).list_element_count() as isize) { + copy_message( arena, - dst, segment_id, - (*src).list_inline_composite_word_count() + 1, - WirePointerKind::List); + cap_table, + dst_refs.offset(ii * BYTES_PER_WORD as isize) as *mut WirePointer, + src_refs.offset(ii), + ); + } + (*dst) + .set_list_size_and_count(ElementSize::Pointer, (*src).list_element_count()); + (dst_refs, dst, segment_id) + } + ElementSize::InlineComposite => { + let src_ptr = (*src).target(); + let (dst_ptr, dst, segment_id) = allocate( + arena, + dst, + segment_id, + (*src).list_inline_composite_word_count() + 1, + WirePointerKind::List, + ); - (*dst).set_list_inline_composite((*src).list_inline_composite_word_count()); + (*dst).set_list_inline_composite((*src).list_inline_composite_word_count()); - let src_tag: *const WirePointer = src_ptr as _; - ptr::copy_nonoverlapping(src_tag, dst_ptr as *mut WirePointer, 1); + let src_tag: *const WirePointer = src_ptr as _; + ptr::copy_nonoverlapping(src_tag, dst_ptr as *mut WirePointer, 1); - let mut src_element = src_ptr.add(BYTES_PER_WORD); - let mut dst_element = dst_ptr.add(BYTES_PER_WORD); + let mut src_element = src_ptr.add(BYTES_PER_WORD); + let mut dst_element = dst_ptr.add(BYTES_PER_WORD); - if (*src_tag).kind() != WirePointerKind::Struct { - panic!("unsupported INLINE_COMPOSITE list"); - } - for _ in 0 .. (*src_tag).inline_composite_list_element_count() { - copy_struct(arena, - segment_id, - cap_table, - dst_element, - src_element, - (*src_tag).struct_data_size() as isize, - (*src_tag).struct_ptr_count() as isize); - src_element = src_element.offset(BYTES_PER_WORD as isize * (*src_tag).struct_word_size() as isize); - dst_element = dst_element.offset(BYTES_PER_WORD as isize * (*src_tag).struct_word_size() as isize); - } - (dst_ptr, dst, segment_id) + if (*src_tag).kind() != WirePointerKind::Struct { + panic!("unsupported INLINE_COMPOSITE list"); } + for _ in 0..(*src_tag).inline_composite_list_element_count() { + copy_struct( + arena, + segment_id, + cap_table, + dst_element, + src_element, + (*src_tag).struct_data_size() as isize, + (*src_tag).struct_ptr_count() as isize, + ); + src_element = src_element.offset( + BYTES_PER_WORD as isize * (*src_tag).struct_word_size() as isize, + ); + dst_element = dst_element.offset( + BYTES_PER_WORD as isize * (*src_tag).struct_word_size() as isize, + ); + } + (dst_ptr, dst, segment_id) } - } + }, WirePointerKind::Other => { panic!("Unchecked message contained an OTHER pointer.") } @@ -877,9 +985,11 @@ mod wire_helpers { pub unsafe fn transfer_pointer( arena: &dyn BuilderArena, - dst_segment_id: u32, dst: *mut WirePointer, - src_segment_id: u32, src: *mut WirePointer) - { + dst_segment_id: u32, + dst: *mut WirePointer, + src_segment_id: u32, + src: *mut WirePointer, + ) { //# Make *dst point to the same object as *src. Both must //# reside in the same message, but can be in different //# segments. Not always-inline because this is rarely used. @@ -896,7 +1006,14 @@ mod wire_helpers { if (*src).is_null() { ptr::write_bytes(dst, 0, 1); } else if (*src).is_positional() { - transfer_pointer_split(arena, dst_segment_id, dst, src_segment_id, src, (*src).mut_target()); + transfer_pointer_split( + arena, + dst_segment_id, + dst, + src_segment_id, + src, + (*src).mut_target(), + ); } else { ptr::copy_nonoverlapping(src, dst, 1); } @@ -904,10 +1021,12 @@ mod wire_helpers { pub unsafe fn transfer_pointer_split( arena: &dyn BuilderArena, - dst_segment_id: u32, dst: *mut WirePointer, - src_segment_id: u32, src_tag: *mut WirePointer, - src_ptr: *mut u8) - { + dst_segment_id: u32, + dst: *mut WirePointer, + src_segment_id: u32, + src_tag: *mut WirePointer, + src_ptr: *mut u8, + ) { // Like the other transfer_pointer, but splits src into a tag and a // target. Particularly useful for OrphanBuilder. @@ -930,13 +1049,15 @@ mod wire_helpers { //# Darn, need a double-far. let (far_segment_id, word_idx) = arena.allocate_anywhere(2); let (seg_start, _seg_len) = arena.get_segment_mut(far_segment_id); - let landing_pad: *mut WirePointer = (seg_start as *mut WirePointer).offset(word_idx as isize); + let landing_pad: *mut WirePointer = + (seg_start as *mut WirePointer).offset(word_idx as isize); let (src_seg_start, _seg_len) = arena.get_segment_mut(src_segment_id); (*landing_pad).set_far( false, - ((src_ptr as usize - src_seg_start as usize) / BYTES_PER_WORD) as u32); + ((src_ptr as usize - src_seg_start as usize) / BYTES_PER_WORD) as u32, + ); (*landing_pad).set_far_segment_id(src_segment_id); let landing_pad1 = landing_pad.offset(1); @@ -945,7 +1066,8 @@ mod wire_helpers { ptr::copy_nonoverlapping( &(*src_tag).upper32bits, &mut (*landing_pad1).upper32bits, - 1); + 1, + ); (*dst).set_far(true, word_idx); (*dst).set_far_segment_id(far_segment_id); @@ -954,10 +1076,14 @@ mod wire_helpers { //# Simple landing pad is just a pointer. let (seg_start, seg_len) = arena.get_segment_mut(src_segment_id); assert!(landing_pad_word < seg_len); - let landing_pad: *mut WirePointer = (seg_start as *mut WirePointer).offset(landing_pad_word as isize); + let landing_pad: *mut WirePointer = + (seg_start as *mut WirePointer).offset(landing_pad_word as isize); (*landing_pad).set_kind_and_target((*src_tag).kind(), src_ptr); - ptr::copy_nonoverlapping(&(*src_tag).upper32bits, - &mut (*landing_pad).upper32bits, 1); + ptr::copy_nonoverlapping( + &(*src_tag).upper32bits, + &mut (*landing_pad).upper32bits, + 1, + ); (*dst).set_far(false, landing_pad_word); (*dst).set_far_segment_id(src_segment_id); @@ -972,14 +1098,15 @@ mod wire_helpers { reff: *mut WirePointer, segment_id: u32, cap_table: CapTableBuilder, - size: StructSize) -> StructBuilder<'_> - { + size: StructSize, + ) -> StructBuilder<'_> { let (ptr, reff, segment_id) = allocate( arena, reff, segment_id, size.total(), - WirePointerKind::Struct); + WirePointerKind::Struct, + ); (*reff).set_struct_size(size); StructBuilder { @@ -1000,18 +1127,30 @@ mod wire_helpers { mut segment_id: u32, cap_table: CapTableBuilder, size: StructSize, - default: Option<&'a [crate::Word]>) -> Result> - { + default: Option<&'a [crate::Word]>, + ) -> Result> { let mut ref_target = (*reff).mut_target(); if (*reff).is_null() { match default { - None => return Ok(init_struct_pointer(arena, reff, segment_id, cap_table, size)), - Some(d) if (*(d.as_ptr() as *const WirePointer)).is_null() => - return Ok(init_struct_pointer(arena, reff, segment_id, cap_table, size)), + None => { + return Ok(init_struct_pointer( + arena, reff, segment_id, cap_table, size, + )) + } + Some(d) if (*(d.as_ptr() as *const WirePointer)).is_null() => { + return Ok(init_struct_pointer( + arena, reff, segment_id, cap_table, size, + )) + } Some(d) => { - let (new_ref_target, new_reff, new_segment_id) = - copy_message(arena, segment_id, cap_table, reff, d.as_ptr() as *const WirePointer); + let (new_ref_target, new_reff, new_segment_id) = copy_message( + arena, + segment_id, + cap_table, + reff, + d.as_ptr() as *const WirePointer, + ); reff = new_reff; segment_id = new_segment_id; ref_target = new_ref_target; @@ -1019,15 +1158,19 @@ mod wire_helpers { } } - let (old_ptr, old_ref, old_segment_id) = follow_builder_fars(arena, reff, ref_target, segment_id)?; + let (old_ptr, old_ref, old_segment_id) = + follow_builder_fars(arena, reff, ref_target, segment_id)?; if (*old_ref).kind() != WirePointerKind::Struct { return Err(Error::failed( - "Message contains non-struct pointer where struct pointer was expected.".to_string())); + "Message contains non-struct pointer where struct pointer was expected." + .to_string(), + )); } let old_data_size = (*old_ref).struct_data_size(); let old_pointer_count = (*old_ref).struct_ptr_count(); - let old_pointer_section: *mut WirePointer = old_ptr.offset(old_data_size as isize * BYTES_PER_WORD as isize) as *mut _; + let old_pointer_section: *mut WirePointer = + old_ptr.offset(old_data_size as isize * BYTES_PER_WORD as isize) as *mut _; if old_data_size < size.data || old_pointer_count < size.pointers { //# The space allocated for this struct is too small. @@ -1038,12 +1181,14 @@ mod wire_helpers { let new_data_size = ::core::cmp::max(old_data_size, size.data); let new_pointer_count = ::core::cmp::max(old_pointer_count, size.pointers); - let total_size = u32::from(new_data_size) + u32::from(new_pointer_count) * WORDS_PER_POINTER as u32; + let total_size = + u32::from(new_data_size) + u32::from(new_pointer_count) * WORDS_PER_POINTER as u32; //# Don't let allocate() zero out the object just yet. zero_pointer_and_fars(arena, segment_id, reff)?; - let (ptr, reff, segment_id) = allocate(arena, reff, segment_id, total_size, WirePointerKind::Struct); + let (ptr, reff, segment_id) = + allocate(arena, reff, segment_id, total_size, WirePointerKind::Struct); (*reff).set_struct_size_from_pieces(new_data_size, new_pointer_count); // Copy data section. @@ -1051,13 +1196,23 @@ mod wire_helpers { ptr::copy_nonoverlapping(old_ptr, ptr, old_data_size as usize * BYTES_PER_WORD); //# Copy pointer section. - let new_pointer_section: *mut WirePointer = ptr.offset(new_data_size as isize * BYTES_PER_WORD as isize) as *mut _; + let new_pointer_section: *mut WirePointer = + ptr.offset(new_data_size as isize * BYTES_PER_WORD as isize) as *mut _; for i in 0..old_pointer_count as isize { - transfer_pointer(arena, segment_id, new_pointer_section.offset(i), - old_segment_id, old_pointer_section.offset(i)); + transfer_pointer( + arena, + segment_id, + new_pointer_section.offset(i), + old_segment_id, + old_pointer_section.offset(i), + ); } - ptr::write_bytes(old_ptr, 0, (old_data_size as usize + old_pointer_count as usize) * BYTES_PER_WORD); + ptr::write_bytes( + old_ptr, + 0, + (old_data_size as usize + old_pointer_count as usize) * BYTES_PER_WORD, + ); Ok(StructBuilder { arena, @@ -1066,7 +1221,7 @@ mod wire_helpers { data: ptr as *mut _, pointers: new_pointer_section, data_size: u32::from(new_data_size) * BITS_PER_WORD as u32, - pointer_count: new_pointer_count + pointer_count: new_pointer_count, }) } else { Ok(StructBuilder { @@ -1076,7 +1231,7 @@ mod wire_helpers { data: old_ptr, pointers: old_pointer_section, data_size: u32::from(old_data_size) * BITS_PER_WORD as u32, - pointer_count: old_pointer_count + pointer_count: old_pointer_count, }) } } @@ -1088,16 +1243,19 @@ mod wire_helpers { segment_id: u32, cap_table: CapTableBuilder, element_count: ElementCount32, - element_size: ElementSize) -> ListBuilder<'_> - { - assert!(element_size != InlineComposite, - "Should have called initStructListPointer() instead"); + element_size: ElementSize, + ) -> ListBuilder<'_> { + assert!( + element_size != InlineComposite, + "Should have called initStructListPointer() instead" + ); let data_size = data_bits_per_element(element_size); let pointer_count = pointers_per_element(element_size); let step = data_size + pointer_count * BITS_PER_POINTER as u32; let word_count = round_bits_up_to_words(u64::from(element_count) * u64::from(step)); - let (ptr, reff, segment_id) = allocate(arena, reff, segment_id, word_count, WirePointerKind::List); + let (ptr, reff, segment_id) = + allocate(arena, reff, segment_id, word_count, WirePointerKind::List); (*reff).set_list_size_and_count(element_size, element_count); @@ -1110,7 +1268,7 @@ mod wire_helpers { element_count, element_size, struct_data_size: data_size, - struct_pointer_count: pointer_count as u16 + struct_pointer_count: pointer_count as u16, } } @@ -1121,22 +1279,27 @@ mod wire_helpers { segment_id: u32, cap_table: CapTableBuilder, element_count: ElementCount32, - element_size: StructSize) -> ListBuilder<'_> - { + element_size: StructSize, + ) -> ListBuilder<'_> { let words_per_element = element_size.total(); //# Allocate the list, prefixed by a single WirePointer. let word_count: WordCount32 = element_count * words_per_element; - let (ptr, reff, segment_id) = allocate(arena, - reff, - segment_id, - POINTER_SIZE_IN_WORDS as u32 + word_count, - WirePointerKind::List); + let (ptr, reff, segment_id) = allocate( + arena, + reff, + segment_id, + POINTER_SIZE_IN_WORDS as u32 + word_count, + WirePointerKind::List, + ); let ptr = ptr as *mut WirePointer; //# Initialize the pointer. (*reff).set_list_inline_composite(word_count); - (*ptr).set_kind_and_inline_composite_list_element_count(WirePointerKind::Struct, element_count); + (*ptr).set_kind_and_inline_composite_list_element_count( + WirePointerKind::Struct, + element_count, + ); (*ptr).set_struct_size(element_size); let ptr1 = ptr.add(POINTER_SIZE_IN_WORDS); @@ -1150,7 +1313,7 @@ mod wire_helpers { element_count, element_size: ElementSize::InlineComposite, struct_data_size: u32::from(element_size.data) * (BITS_PER_WORD as u32), - struct_pointer_count: element_size.pointers + struct_pointer_count: element_size.pointers, } } @@ -1161,10 +1324,12 @@ mod wire_helpers { mut orig_segment_id: u32, cap_table: CapTableBuilder, element_size: ElementSize, - default_value: *const u8) -> Result> - { - assert!(element_size != InlineComposite, - "Use get_writable_struct_list_pointer() for struct lists"); + default_value: *const u8, + ) -> Result> { + assert!( + element_size != InlineComposite, + "Use get_writable_struct_list_pointer() for struct lists" + ); let mut orig_ref_target = (*orig_ref).mut_target(); @@ -1173,7 +1338,12 @@ mod wire_helpers { return Ok(ListBuilder::new_default()); } let (new_orig_ref_target, new_orig_ref, new_orig_segment_id) = copy_message( - arena, orig_segment_id, cap_table, orig_ref, default_value as *const WirePointer); + arena, + orig_segment_id, + cap_table, + orig_ref, + default_value as *const WirePointer, + ); orig_ref_target = new_orig_ref_target; orig_ref = new_orig_ref; orig_segment_id = new_orig_segment_id; @@ -1189,7 +1359,9 @@ mod wire_helpers { if (*reff).kind() != WirePointerKind::List { return Err(Error::failed( - "Called get_writable_list_pointer() but existing pointer is not a list.".to_string())); + "Called get_writable_list_pointer() but existing pointer is not a list." + .to_string(), + )); } let old_size = (*reff).list_element_size(); @@ -1206,7 +1378,8 @@ mod wire_helpers { if (*tag).kind() != WirePointerKind::Struct { return Err(Error::failed( - "InlineComposite list with non-STRUCT elements not supported.".to_string())); + "InlineComposite list with non-STRUCT elements not supported.".to_string(), + )); } ptr = ptr.add(BYTES_PER_WORD); @@ -1218,18 +1391,21 @@ mod wire_helpers { Void => {} // Anything is a valid upgrade from Void. Bit => { return Err(Error::failed( - "Found struct list where bit list was expected.".to_string())); + "Found struct list where bit list was expected.".to_string(), + )); } Byte | TwoBytes | FourBytes | EightBytes => { if data_size < 1 { return Err(Error::failed( - "Existing list value is incompatible with expected type.".to_string())); + "Existing list value is incompatible with expected type.".to_string(), + )); } } Pointer => { if pointer_count < 1 { return Err(Error::failed( - "Existing list value is incompatible with expected type.".to_string())); + "Existing list value is incompatible with expected type.".to_string(), + )); } // Adjust the pointer to point at the reference segment. ptr = ptr.offset(data_size as isize * BYTES_PER_WORD as isize); @@ -1249,16 +1425,18 @@ mod wire_helpers { element_size: ElementSize::InlineComposite, step: (*tag).struct_word_size() * BITS_PER_WORD as u32, struct_data_size: u32::from(data_size) * BITS_PER_WORD as u32, - struct_pointer_count: pointer_count + struct_pointer_count: pointer_count, }) } else { let data_size = data_bits_per_element(old_size); let pointer_count = pointers_per_element(old_size); - if data_size < data_bits_per_element(element_size) || - pointer_count < pointers_per_element(element_size) { + if data_size < data_bits_per_element(element_size) + || pointer_count < pointers_per_element(element_size) + { return Err(Error::failed( - "Existing list value is incompatible with expected type.".to_string())); + "Existing list value is incompatible with expected type.".to_string(), + )); } let step = data_size + pointer_count * BITS_PER_POINTER as u32; @@ -1272,7 +1450,7 @@ mod wire_helpers { element_count: (*reff).list_element_count(), element_size: old_size, struct_data_size: data_size, - struct_pointer_count: pointer_count as u16 + struct_pointer_count: pointer_count as u16, }) } } @@ -1284,8 +1462,8 @@ mod wire_helpers { mut orig_segment_id: u32, cap_table: CapTableBuilder, element_size: StructSize, - default_value: *const u8) -> Result> - { + default_value: *const u8, + ) -> Result> { let mut orig_ref_target = (*orig_ref).mut_target(); if (*orig_ref).is_null() { @@ -1293,7 +1471,12 @@ mod wire_helpers { return Ok(ListBuilder::new_default()); } let (new_orig_ref_target, new_orig_ref, new_orig_segment_id) = copy_message( - arena, orig_segment_id, cap_table, orig_ref, default_value as *const WirePointer); + arena, + orig_segment_id, + cap_table, + orig_ref, + default_value as *const WirePointer, + ); orig_ref_target = new_orig_ref_target; orig_ref = new_orig_ref; orig_segment_id = new_orig_segment_id; @@ -1306,7 +1489,9 @@ mod wire_helpers { if (*old_ref).kind() != WirePointerKind::List { return Err(Error::failed( - "Called get_writable_struct_list_pointer() but existing pointer is not a list.".to_string())); + "Called get_writable_struct_list_pointer() but existing pointer is not a list." + .to_string(), + )); } let old_size = (*old_ref).list_element_size(); @@ -1318,12 +1503,14 @@ mod wire_helpers { old_ptr = old_ptr.add(BYTES_PER_WORD); if (*old_tag).kind() != WirePointerKind::Struct { return Err(Error::failed( - "InlineComposite list with non-STRUCT elements not supported.".to_string())); + "InlineComposite list with non-STRUCT elements not supported.".to_string(), + )); } let old_data_size = (*old_tag).struct_data_size(); let old_pointer_count = (*old_tag).struct_ptr_count(); - let old_step = u32::from(old_data_size) + u32::from(old_pointer_count) * WORDS_PER_POINTER as u32; + let old_step = + u32::from(old_data_size) + u32::from(old_pointer_count) * WORDS_PER_POINTER as u32; let element_count = (*old_tag).inline_composite_list_element_count(); if old_data_size >= element_size.data && old_pointer_count >= element_size.pointers { @@ -1337,7 +1524,7 @@ mod wire_helpers { element_size: ElementSize::InlineComposite, step: old_step * BITS_PER_WORD as u32, struct_data_size: u32::from(old_data_size) * BITS_PER_WORD as u32, - struct_pointer_count: old_pointer_count + struct_pointer_count: old_pointer_count, }); } @@ -1346,19 +1533,27 @@ mod wire_helpers { let new_data_size = ::core::cmp::max(old_data_size, element_size.data); let new_pointer_count = ::core::cmp::max(old_pointer_count, element_size.pointers); - let new_step = u32::from(new_data_size) + u32::from(new_pointer_count) * WORDS_PER_POINTER as u32; + let new_step = + u32::from(new_data_size) + u32::from(new_pointer_count) * WORDS_PER_POINTER as u32; let total_size = new_step * element_count; // Don't let allocate() zero out the object just yet. zero_pointer_and_fars(arena, orig_segment_id, orig_ref)?; - let (mut new_ptr, new_ref, new_segment_id) = - allocate(arena, orig_ref, orig_segment_id, - total_size + POINTER_SIZE_IN_WORDS as u32, WirePointerKind::List); + let (mut new_ptr, new_ref, new_segment_id) = allocate( + arena, + orig_ref, + orig_segment_id, + total_size + POINTER_SIZE_IN_WORDS as u32, + WirePointerKind::List, + ); (*new_ref).set_list_inline_composite(total_size); let new_tag: *mut WirePointer = new_ptr as *mut _; - (*new_tag).set_kind_and_inline_composite_list_element_count(WirePointerKind::Struct, element_count); + (*new_tag).set_kind_and_inline_composite_list_element_count( + WirePointerKind::Struct, + element_count, + ); (*new_tag).set_struct_size_from_pieces(new_data_size, new_pointer_count); new_ptr = new_ptr.add(BYTES_PER_WORD); @@ -1372,17 +1567,24 @@ mod wire_helpers { let new_pointer_section = dst.offset(new_data_size as isize); let old_pointer_section = src.offset(old_data_size as isize); for jj in 0..(old_pointer_count as isize) { - transfer_pointer(arena, new_segment_id, - new_pointer_section.offset(jj), - old_segment_id, old_pointer_section.offset(jj)); + transfer_pointer( + arena, + new_segment_id, + new_pointer_section.offset(jj), + old_segment_id, + old_pointer_section.offset(jj), + ); } dst = dst.offset(new_step as isize); src = src.offset(old_step as isize); } - ptr::write_bytes(old_ptr.offset(-(BYTES_PER_WORD as isize)), 0, - (u64::from(old_step) * u64::from(element_count)) as usize * BYTES_PER_WORD); + ptr::write_bytes( + old_ptr.offset(-(BYTES_PER_WORD as isize)), + 0, + (u64::from(old_step) * u64::from(element_count)) as usize * BYTES_PER_WORD, + ); Ok(ListBuilder { arena, @@ -1406,14 +1608,22 @@ mod wire_helpers { if old_size == ElementSize::Void { // Nothing to copy, just allocate a new list. Ok(init_struct_list_pointer( - arena, orig_ref, orig_segment_id, cap_table, element_count, element_size)) + arena, + orig_ref, + orig_segment_id, + cap_table, + element_count, + element_size, + )) } else { // Upgrade to an inline composite list. if old_size == ElementSize::Bit { return Err(Error::failed( "Found bit list where struct list was expected; upgrading boolean \ - lists to struct lists is no longer supported.".to_string())); + lists to struct lists is no longer supported." + .to_string(), + )); } let mut new_data_size = element_size.data; @@ -1426,19 +1636,27 @@ mod wire_helpers { new_data_size = ::core::cmp::max(new_data_size, 1); } - let new_step = u32::from(new_data_size) + u32::from(new_pointer_count) * WORDS_PER_POINTER as u32; + let new_step = u32::from(new_data_size) + + u32::from(new_pointer_count) * WORDS_PER_POINTER as u32; let total_words = element_count * new_step; // Don't let allocate() zero out the object just yet. zero_pointer_and_fars(arena, orig_segment_id, orig_ref)?; - let (mut new_ptr, new_ref, new_segment_id) = - allocate(arena, orig_ref, orig_segment_id, - total_words + POINTER_SIZE_IN_WORDS as u32, WirePointerKind::List); + let (mut new_ptr, new_ref, new_segment_id) = allocate( + arena, + orig_ref, + orig_segment_id, + total_words + POINTER_SIZE_IN_WORDS as u32, + WirePointerKind::List, + ); (*new_ref).set_list_inline_composite(total_words); let tag: *mut WirePointer = new_ptr as *mut _; - (*tag).set_kind_and_inline_composite_list_element_count(WirePointerKind::Struct, element_count); + (*tag).set_kind_and_inline_composite_list_element_count( + WirePointerKind::Struct, + element_count, + ); (*tag).set_struct_size_from_pieces(new_data_size, new_pointer_count); new_ptr = new_ptr.add(BYTES_PER_WORD); @@ -1462,8 +1680,11 @@ mod wire_helpers { } // Zero out old location. - ptr::write_bytes(old_ptr, 0, - round_bits_up_to_bytes(u64::from(old_step) * u64::from(element_count)) as usize); + ptr::write_bytes( + old_ptr, + 0, + round_bits_up_to_bytes(u64::from(old_step) * u64::from(element_count)) as usize, + ); Ok(ListBuilder { arena, @@ -1474,7 +1695,7 @@ mod wire_helpers { element_size: ElementSize::InlineComposite, step: new_step * BITS_PER_WORD as u32, struct_data_size: u32::from(new_data_size) * BITS_PER_WORD as u32, - struct_pointer_count: new_pointer_count + struct_pointer_count: new_pointer_count, }) } } @@ -1485,14 +1706,19 @@ mod wire_helpers { arena: &dyn BuilderArena, reff: *mut WirePointer, segment_id: u32, - size: ByteCount32) -> SegmentAnd> - { + size: ByteCount32, + ) -> SegmentAnd> { //# The byte list must include a NUL terminator. let byte_size = size + 1; //# Allocate the space. - let (ptr, reff, segment_id) = - allocate(arena, reff, segment_id, round_bytes_up_to_words(byte_size), WirePointerKind::List); + let (ptr, reff, segment_id) = allocate( + arena, + reff, + segment_id, + round_bytes_up_to_words(byte_size), + WirePointerKind::List, + ); //# Initialize the pointer. (*reff).set_list_size_and_count(Byte, byte_size); @@ -1500,7 +1726,7 @@ mod wire_helpers { SegmentAnd { segment_id, value: text::Builder::new(slice::from_raw_parts_mut(ptr, size as usize), 0) - .expect("empty text builder should be valid utf-8") + .expect("empty text builder should be valid utf-8"), } } @@ -1509,8 +1735,8 @@ mod wire_helpers { arena: &'a dyn BuilderArena, reff: *mut WirePointer, segment_id: u32, - value: &str) -> SegmentAnd> - { + value: &str, + ) -> SegmentAnd> { let value_bytes = value.as_bytes(); // TODO make sure the string is not longer than 2 ** 29. let mut allocation = init_text_pointer(arena, reff, segment_id, value_bytes.len() as u32); @@ -1523,14 +1749,19 @@ mod wire_helpers { arena: &'a dyn BuilderArena, mut reff: *mut WirePointer, mut segment_id: u32, - default: Option<&'a [crate::Word]>) -> Result> - { + default: Option<&'a [crate::Word]>, + ) -> Result> { let ref_target = if (*reff).is_null() { match default { None => return text::Builder::new(&mut [], 0), Some(d) => { - let (new_ref_target, new_reff, new_segment_id) = - copy_message(arena, segment_id, CapTableBuilder::Plain(::core::ptr::null_mut()), reff, d.as_ptr() as *const _); + let (new_ref_target, new_reff, new_segment_id) = copy_message( + arena, + segment_id, + CapTableBuilder::Plain(::core::ptr::null_mut()), + reff, + d.as_ptr() as *const _, + ); reff = new_reff; segment_id = new_segment_id; new_ref_target @@ -1544,21 +1775,29 @@ mod wire_helpers { if (*reff).kind() != WirePointerKind::List { return Err(Error::failed( - "Called get_writable_text_pointer() but existing pointer is not a list.".to_string())); + "Called get_writable_text_pointer() but existing pointer is not a list." + .to_string(), + )); } if (*reff).list_element_size() != Byte { return Err(Error::failed( - "Called get_writable_text_pointer() but existing list pointer is not byte-sized.".to_string())); + "Called get_writable_text_pointer() but existing list pointer is not byte-sized." + .to_string(), + )); } let count = (*reff).list_element_count(); if count == 0 || *ptr.offset((count - 1) as isize) != 0 { return Err(Error::failed( - "Text blob missing NUL terminator.".to_string())); + "Text blob missing NUL terminator.".to_string(), + )); } // Subtract 1 from the size for the NUL terminator. - text::Builder::new(slice::from_raw_parts_mut(ptr, (count - 1) as usize), count - 1) + text::Builder::new( + slice::from_raw_parts_mut(ptr, (count - 1) as usize), + count - 1, + ) } #[inline] @@ -1566,16 +1805,24 @@ mod wire_helpers { arena: &dyn BuilderArena, reff: *mut WirePointer, segment_id: u32, - size: ByteCount32) -> SegmentAnd> - { + size: ByteCount32, + ) -> SegmentAnd> { //# Allocate the space. - let (ptr, reff, segment_id) = - allocate(arena, reff, segment_id, round_bytes_up_to_words(size), WirePointerKind::List); + let (ptr, reff, segment_id) = allocate( + arena, + reff, + segment_id, + round_bytes_up_to_words(size), + WirePointerKind::List, + ); //# Initialize the pointer. (*reff).set_list_size_and_count(Byte, size); - SegmentAnd { segment_id, value: data::builder_from_raw_parts(ptr, size) } + SegmentAnd { + segment_id, + value: data::builder_from_raw_parts(ptr, size), + } } #[inline] @@ -1583,11 +1830,10 @@ mod wire_helpers { arena: &'a dyn BuilderArena, reff: *mut WirePointer, segment_id: u32, - value: &[u8]) -> SegmentAnd> - { + value: &[u8], + ) -> SegmentAnd> { let allocation = init_data_pointer(arena, reff, segment_id, value.len() as u32); - ptr::copy_nonoverlapping(value.as_ptr(), allocation.value.as_mut_ptr(), - value.len()); + ptr::copy_nonoverlapping(value.as_ptr(), allocation.value.as_mut_ptr(), value.len()); allocation } @@ -1596,14 +1842,19 @@ mod wire_helpers { arena: &'a dyn BuilderArena, mut reff: *mut WirePointer, mut segment_id: u32, - default: Option<&'a [crate::Word]>) -> Result> - { + default: Option<&'a [crate::Word]>, + ) -> Result> { let ref_target = if (*reff).is_null() { match default { None => return Ok(&mut []), Some(d) => { - let (new_ref_target, new_reff, new_segment_id) = - copy_message(arena, segment_id, CapTableBuilder::Plain(core::ptr::null_mut()), reff, d.as_ptr() as *const _); + let (new_ref_target, new_reff, new_segment_id) = copy_message( + arena, + segment_id, + CapTableBuilder::Plain(core::ptr::null_mut()), + reff, + d.as_ptr() as *const _, + ); reff = new_reff; segment_id = new_segment_id; new_ref_target @@ -1617,14 +1868,21 @@ mod wire_helpers { if (*reff).kind() != WirePointerKind::List { return Err(Error::failed( - "Called get_writable_data_pointer() but existing pointer is not a list.".to_string())); + "Called get_writable_data_pointer() but existing pointer is not a list." + .to_string(), + )); } if (*reff).list_element_size() != Byte { return Err(Error::failed( - "Called get_writable_data_pointer() but existing list pointer is not byte-sized.".to_string())); + "Called get_writable_data_pointer() but existing list pointer is not byte-sized." + .to_string(), + )); } - Ok(data::builder_from_raw_parts(ptr, (*reff).list_element_count())) + Ok(data::builder_from_raw_parts( + ptr, + (*reff).list_element_count(), + )) } pub unsafe fn set_struct_pointer( @@ -1633,15 +1891,17 @@ mod wire_helpers { cap_table: CapTableBuilder, reff: *mut WirePointer, value: StructReader, - canonicalize: bool) -> Result> - { + canonicalize: bool, + ) -> Result> { let mut data_size: ByteCount32 = round_bits_up_to_bytes(u64::from(value.data_size)); let mut ptr_count = value.pointer_count; if canonicalize { // StructReaders should not have bitwidths other than 1, but let's be safe if !(value.data_size == 1 || value.data_size % BITS_PER_BYTE as u32 == 0) { - return Err(Error::failed("struct reader had bitwidth other than 1".to_string())) + return Err(Error::failed( + "struct reader had bitwidth other than 1".to_string(), + )); } if value.data_size == 1 { @@ -1660,7 +1920,7 @@ mod wire_helpers { if last_word == [0; 8] { data_size -= window; } else { - break 'chop + break 'chop; } } } @@ -1686,16 +1946,27 @@ mod wire_helpers { ptr::copy_nonoverlapping::(value.data, ptr, data_size as usize); } - let pointer_section: *mut WirePointer = ptr.offset(data_words as isize * BYTES_PER_WORD as isize) as *mut _; + let pointer_section: *mut WirePointer = + ptr.offset(data_words as isize * BYTES_PER_WORD as isize) as *mut _; for i in 0..ptr_count as isize { - copy_pointer(arena, segment_id, cap_table, pointer_section.offset(i), - value.arena, - value.segment_id, value.cap_table, value.pointers.offset(i), - value.nesting_limit, - canonicalize)?; + copy_pointer( + arena, + segment_id, + cap_table, + pointer_section.offset(i), + value.arena, + value.segment_id, + value.cap_table, + value.pointers.offset(i), + value.nesting_limit, + canonicalize, + )?; } - Ok(SegmentAnd { segment_id, value: ptr }) + Ok(SegmentAnd { + segment_id, + value: ptr, + }) } pub fn set_capability_pointer( @@ -1703,10 +1974,12 @@ mod wire_helpers { _segment_id: u32, mut cap_table: CapTableBuilder, reff: *mut WirePointer, - cap: Box) - { + cap: Box, + ) { // TODO if ref is not null, zero object. - unsafe { (*reff).set_cap(cap_table.inject_cap(cap) as u32); } + unsafe { + (*reff).set_cap(cap_table.inject_cap(cap) as u32); + } } pub unsafe fn set_list_pointer( @@ -1715,9 +1988,10 @@ mod wire_helpers { cap_table: CapTableBuilder, reff: *mut WirePointer, value: ListReader, - canonicalize: bool) -> Result> - { - let total_size = round_bits_up_to_words(u64::from(value.element_count) * u64::from(value.step)); + canonicalize: bool, + ) -> Result> { + let total_size = + round_bits_up_to_words(u64::from(value.element_count) * u64::from(value.step)); if value.element_size != ElementSize::InlineComposite { //# List of non-structs. @@ -1727,14 +2001,19 @@ mod wire_helpers { if value.struct_pointer_count == 1 { //# List of pointers. (*reff).set_list_size_and_count(Pointer, value.element_count); - for i in 0.. value.element_count as isize { - copy_pointer(arena, segment_id, cap_table, - (ptr as *mut WirePointer).offset(i), - value.arena, - value.segment_id, value.cap_table, - (value.ptr as *const WirePointer).offset(i), - value.nesting_limit, - canonicalize)?; + for i in 0..value.element_count as isize { + copy_pointer( + arena, + segment_id, + cap_table, + (ptr as *mut WirePointer).offset(i), + value.arena, + value.segment_id, + value.cap_table, + (value.ptr as *const WirePointer).offset(i), + value.nesting_limit, + canonicalize, + )?; } } else { //# List of data. @@ -1745,7 +2024,9 @@ mod wire_helpers { 16 => TwoBytes, 32 => FourBytes, 64 => EightBytes, - _ => { panic!("invalid list step size: {}", value.step) } + _ => { + panic!("invalid list step size: {}", value.step) + } }; (*reff).set_list_size_and_count(element_size, value.element_count); @@ -1754,11 +2035,15 @@ mod wire_helpers { // TODO(perf) Is ptr::copy_nonoverlapping faster if word-aligned? // If so, then perhaps we should only drop to the byte-index level // in the canonicalize=true case. - let whole_byte_size = u64::from(value.element_count) * u64::from(value.step) / BITS_PER_BYTE as u64; - ptr::copy_nonoverlapping(value.ptr as *const u8, - ptr as *mut u8, - whole_byte_size as usize); - let leftover_bits = u64::from(value.element_count) * u64::from(value.step) % BITS_PER_BYTE as u64; + let whole_byte_size = + u64::from(value.element_count) * u64::from(value.step) / BITS_PER_BYTE as u64; + ptr::copy_nonoverlapping( + value.ptr as *const u8, + ptr as *mut u8, + whole_byte_size as usize, + ); + let leftover_bits = + u64::from(value.element_count) * u64::from(value.step) % BITS_PER_BYTE as u64; if leftover_bits > 0 { let mask: u8 = (1 << leftover_bits as u8) - 1; @@ -1767,7 +2052,10 @@ mod wire_helpers { } } - Ok(SegmentAnd { segment_id, value: ptr }) + Ok(SegmentAnd { + segment_id, + value: ptr, + }) } else { //# List of structs. @@ -1786,9 +2074,10 @@ mod wire_helpers { let end = local_data_size * BYTES_PER_WORD as u32; let window = BYTES_PER_WORD as u32; let start = end - window; - let last_word = &se.get_data_section_as_blob()[start as usize..end as usize]; + let last_word = + &se.get_data_section_as_blob()[start as usize..end as usize]; if last_word != [0; 8] { - break 'data_chop + break 'data_chop; } else { local_data_size -= 1; } @@ -1797,7 +2086,9 @@ mod wire_helpers { data_size = local_data_size; } let mut local_ptr_count = decl_pointer_count; - while local_ptr_count != 0 && se.get_pointer_field(local_ptr_count as usize - 1).is_null() { + while local_ptr_count != 0 + && se.get_pointer_field(local_ptr_count as usize - 1).is_null() + { local_ptr_count -= 1; } if local_ptr_count > ptr_count { @@ -1810,49 +2101,74 @@ mod wire_helpers { ptr_count = decl_pointer_count; } - let (ptr, reff, segment_id) = - allocate(arena, reff, segment_id, - total_size + POINTER_SIZE_IN_WORDS as u32, WirePointerKind::List); + let (ptr, reff, segment_id) = allocate( + arena, + reff, + segment_id, + total_size + POINTER_SIZE_IN_WORDS as u32, + WirePointerKind::List, + ); (*reff).set_list_inline_composite(total_size); let tag: *mut WirePointer = ptr as *mut _; - (*tag).set_kind_and_inline_composite_list_element_count(WirePointerKind::Struct, value.element_count); + (*tag).set_kind_and_inline_composite_list_element_count( + WirePointerKind::Struct, + value.element_count, + ); (*tag).set_struct_size_from_pieces(data_size as u16, ptr_count); let mut dst = ptr.add(BYTES_PER_WORD); let mut src: *const u8 = value.ptr; - for _ in 0.. value.element_count { + for _ in 0..value.element_count { ptr::copy_nonoverlapping(src, dst, data_size as usize * BYTES_PER_WORD); dst = dst.offset(data_size as isize * BYTES_PER_WORD as isize); src = src.offset(decl_data_size as isize * BYTES_PER_WORD as isize); for _ in 0..ptr_count { - copy_pointer(arena, segment_id, cap_table, dst as *mut _, - value.arena, value.segment_id, value.cap_table, src as *const WirePointer, - value.nesting_limit, canonicalize)?; + copy_pointer( + arena, + segment_id, + cap_table, + dst as *mut _, + value.arena, + value.segment_id, + value.cap_table, + src as *const WirePointer, + value.nesting_limit, + canonicalize, + )?; dst = dst.add(BYTES_PER_WORD); src = src.add(BYTES_PER_WORD); } - src = src.offset((decl_pointer_count - ptr_count) as isize * BYTES_PER_WORD as isize); + src = + src.offset((decl_pointer_count - ptr_count) as isize * BYTES_PER_WORD as isize); } - Ok(SegmentAnd { segment_id, value: ptr }) + Ok(SegmentAnd { + segment_id, + value: ptr, + }) } } pub unsafe fn copy_pointer( dst_arena: &dyn BuilderArena, - dst_segment_id: u32, dst_cap_table: CapTableBuilder, + dst_segment_id: u32, + dst_cap_table: CapTableBuilder, dst: *mut WirePointer, src_arena: &dyn ReaderArena, - src_segment_id: u32, src_cap_table: CapTableReader, + src_segment_id: u32, + src_cap_table: CapTableReader, src: *const WirePointer, nesting_limit: i32, - canonicalize: bool) -> Result> - { + canonicalize: bool, + ) -> Result> { if (*src).is_null() { ptr::write_bytes(dst, 0, 1); - return Ok(SegmentAnd { segment_id: dst_segment_id, value: ptr::null_mut() }); + return Ok(SegmentAnd { + segment_id: dst_segment_id, + value: ptr::null_mut(), + }); } let (mut ptr, src, src_segment_id) = follow_fars(src_arena, src, src_segment_id)?; @@ -1861,33 +2177,46 @@ mod wire_helpers { WirePointerKind::Struct => { if nesting_limit <= 0 { return Err(Error::failed( - "Message is too deeply-nested or contains cycles. See ReaderOptions.".to_string())); + "Message is too deeply-nested or contains cycles. See ReaderOptions." + .to_string(), + )); } - bounds_check(src_arena, src_segment_id, - ptr, (*src).struct_word_size() as usize, - WirePointerKind::Struct)?; + bounds_check( + src_arena, + src_segment_id, + ptr, + (*src).struct_word_size() as usize, + WirePointerKind::Struct, + )?; set_struct_pointer( dst_arena, - dst_segment_id, dst_cap_table, dst, + dst_segment_id, + dst_cap_table, + dst, StructReader { arena: src_arena, segment_id: src_segment_id, cap_table: src_cap_table, data: ptr, - pointers: ptr.offset((*src).struct_data_size() as isize * BYTES_PER_WORD as isize) as *const _, + pointers: ptr + .offset((*src).struct_data_size() as isize * BYTES_PER_WORD as isize) + as *const _, data_size: u32::from((*src).struct_data_size()) * BITS_PER_WORD as u32, pointer_count: (*src).struct_ptr_count(), - nesting_limit: nesting_limit - 1 + nesting_limit: nesting_limit - 1, }, - canonicalize) + canonicalize, + ) } WirePointerKind::List => { let element_size = (*src).list_element_size(); if nesting_limit <= 0 { return Err(Error::failed( - "Message is too deeply-nested or contains cycles. See ReaderOptions.".to_string())); + "Message is too deeply-nested or contains cycles. See ReaderOptions." + .to_string(), + )); } if element_size == InlineComposite { @@ -1896,20 +2225,29 @@ mod wire_helpers { ptr = ptr.add(BYTES_PER_WORD); bounds_check( - src_arena, src_segment_id, ptr.offset(-(BYTES_PER_WORD as isize)), word_count as usize + 1, - WirePointerKind::List)?; + src_arena, + src_segment_id, + ptr.offset(-(BYTES_PER_WORD as isize)), + word_count as usize + 1, + WirePointerKind::List, + )?; if (*tag).kind() != WirePointerKind::Struct { return Err(Error::failed( - "InlineComposite lists of non-STRUCT type are not supported.".to_string())); + "InlineComposite lists of non-STRUCT type are not supported." + .to_string(), + )); } let element_count = (*tag).inline_composite_list_element_count(); let words_per_element = (*tag).struct_word_size(); - if u64::from(words_per_element) * u64::from(element_count) > u64::from(word_count) { + if u64::from(words_per_element) * u64::from(element_count) + > u64::from(word_count) + { return Err(Error::failed( - "InlineComposite list's elements overrun its word count.".to_string())); + "InlineComposite list's elements overrun its word count.".to_string(), + )); } if words_per_element == 0 { @@ -1920,7 +2258,9 @@ mod wire_helpers { set_list_pointer( dst_arena, - dst_segment_id, dst_cap_table, dst, + dst_segment_id, + dst_cap_table, + dst, ListReader { arena: src_arena, segment_id: src_segment_id, @@ -1929,21 +2269,28 @@ mod wire_helpers { element_count, element_size, step: words_per_element * BITS_PER_WORD as u32, - struct_data_size: u32::from((*tag).struct_data_size()) * BITS_PER_WORD as u32, + struct_data_size: u32::from((*tag).struct_data_size()) + * BITS_PER_WORD as u32, struct_pointer_count: (*tag).struct_ptr_count(), - nesting_limit: nesting_limit - 1 + nesting_limit: nesting_limit - 1, }, - canonicalize) + canonicalize, + ) } else { let data_size = data_bits_per_element(element_size); let pointer_count = pointers_per_element(element_size); let step = data_size + pointer_count * BITS_PER_POINTER as u32; let element_count = (*src).list_element_count(); - let word_count = round_bits_up_to_words(u64::from(element_count) * u64::from(step)); + let word_count = + round_bits_up_to_words(u64::from(element_count) * u64::from(step)); - bounds_check(src_arena, - src_segment_id, ptr, - word_count as usize, WirePointerKind::List)?; + bounds_check( + src_arena, + src_segment_id, + ptr, + word_count as usize, + WirePointerKind::List, + )?; if element_size == Void { // Watch out for lists of void, which can claim to be arbitrarily large @@ -1953,41 +2300,46 @@ mod wire_helpers { set_list_pointer( dst_arena, - dst_segment_id, dst_cap_table, dst, + dst_segment_id, + dst_cap_table, + dst, ListReader { arena: src_arena, segment_id: src_segment_id, - cap_table : src_cap_table, + cap_table: src_cap_table, ptr: ptr as *const _, element_count, element_size, step, struct_data_size: data_size, struct_pointer_count: pointer_count as u16, - nesting_limit: nesting_limit - 1 + nesting_limit: nesting_limit - 1, }, - canonicalize) + canonicalize, + ) } } - WirePointerKind::Far => { - Err(Error::failed("Malformed double-far pointer.".to_string())) - } + WirePointerKind::Far => Err(Error::failed("Malformed double-far pointer.".to_string())), WirePointerKind::Other => { if !(*src).is_capability() { return Err(Error::failed("Unknown pointer type.".to_string())); } if canonicalize { - return Err(Error::failed("Cannot create a canonical message with a capability".to_string())); + return Err(Error::failed( + "Cannot create a canonical message with a capability".to_string(), + )); } match src_cap_table.extract_cap((*src).cap_index() as usize) { Some(cap) => { set_capability_pointer(dst_arena, dst_segment_id, dst_cap_table, dst, cap); - Ok(SegmentAnd { segment_id: dst_segment_id, value: ptr::null_mut() }) - } - None => { - Err(Error::failed( - "Message contained invalid capability pointer.".to_string())) + Ok(SegmentAnd { + segment_id: dst_segment_id, + value: ptr::null_mut(), + }) } + None => Err(Error::failed( + "Message contained invalid capability pointer.".to_string(), + )), } } } @@ -2000,13 +2352,14 @@ mod wire_helpers { cap_table: CapTableReader, mut reff: *const WirePointer, default: Option<&'a [crate::Word]>, - nesting_limit: i32) -> Result> - { + nesting_limit: i32, + ) -> Result> { if (*reff).is_null() { match default { None => return Ok(StructReader::new_default()), - Some(d) if (*(d.as_ptr() as *const WirePointer)).is_null() => - return Ok(StructReader::new_default()), + Some(d) if (*(d.as_ptr() as *const WirePointer)).is_null() => { + return Ok(StructReader::new_default()) + } Some(d) => { reff = d.as_ptr() as *const _; arena = &super::NULL_ARENA; @@ -2016,7 +2369,9 @@ mod wire_helpers { } if nesting_limit <= 0 { - return Err(Error::failed("Message is too deeply-nested or contains cycles.".to_string())); + return Err(Error::failed( + "Message is too deeply-nested or contains cycles.".to_string(), + )); } let (ptr, reff, segment_id) = follow_fars(arena, reff, segment_id)?; @@ -2025,12 +2380,18 @@ mod wire_helpers { if (*reff).kind() != WirePointerKind::Struct { return Err(Error::failed( - "Message contains non-struct pointer where struct pointer was expected.".to_string())); + "Message contains non-struct pointer where struct pointer was expected." + .to_string(), + )); } - bounds_check(arena, segment_id, ptr, - (*reff).struct_word_size() as usize, - WirePointerKind::Struct)?; + bounds_check( + arena, + segment_id, + ptr, + (*reff).struct_word_size() as usize, + WirePointerKind::Struct, + )?; Ok(StructReader { arena, @@ -2042,7 +2403,7 @@ mod wire_helpers { pointer_count: (*reff).struct_ptr_count(), nesting_limit: nesting_limit - 1, }) - } + } #[inline] pub unsafe fn read_capability_pointer( @@ -2050,22 +2411,25 @@ mod wire_helpers { _segment_id: u32, cap_table: CapTableReader, reff: *const WirePointer, - _nesting_limit: i32) -> Result> - { + _nesting_limit: i32, + ) -> Result> { if (*reff).is_null() { Err(Error::failed( - "Message contains null capability pointer.".to_string())) + "Message contains null capability pointer.".to_string(), + )) } else if !(*reff).is_capability() { Err(Error::failed( - "Message contains non-capability pointer where capability pointer was expected.".to_string())) + "Message contains non-capability pointer where capability pointer was expected." + .to_string(), + )) } else { let n = (*reff).cap_index() as usize; match cap_table.extract_cap(n) { - Some(client_hook) => { Ok(client_hook) } - None => { - Err(Error::failed( - format!("Message contains invalid capability pointer. Index: {}", n))) - } + Some(client_hook) => Ok(client_hook), + None => Err(Error::failed(format!( + "Message contains invalid capability pointer. Index: {}", + n + ))), } } } @@ -2078,8 +2442,8 @@ mod wire_helpers { mut reff: *const WirePointer, default_value: *const u8, expected_element_size: Option, - nesting_limit: i32) -> Result> - { + nesting_limit: i32, + ) -> Result> { if (*reff).is_null() { if default_value.is_null() || (*(default_value as *const WirePointer)).is_null() { return Ok(ListReader::new_default()); @@ -2096,7 +2460,8 @@ mod wire_helpers { if (*reff).kind() != WirePointerKind::List { return Err(Error::failed( - "Message contains non-list pointer where list pointer was expected".to_string())); + "Message contains non-list pointer where list pointer was expected".to_string(), + )); } let element_size = (*reff).list_element_size(); @@ -2108,13 +2473,18 @@ mod wire_helpers { ptr = ptr.add(BYTES_PER_WORD); - bounds_check(arena, segment_id, ptr.offset(-(BYTES_PER_WORD as isize)), - word_count as usize + 1, - WirePointerKind::List)?; + bounds_check( + arena, + segment_id, + ptr.offset(-(BYTES_PER_WORD as isize)), + word_count as usize + 1, + WirePointerKind::List, + )?; if (*tag).kind() != WirePointerKind::Struct { return Err(Error::failed( - "InlineComposite lists of non-STRUCT type are not supported.".to_string())); + "InlineComposite lists of non-STRUCT type are not supported.".to_string(), + )); } let size = (*tag).inline_composite_list_element_count(); @@ -2124,7 +2494,8 @@ mod wire_helpers { if u64::from(size) * u64::from(words_per_element) > u64::from(word_count) { return Err(Error::failed( - "InlineComposite list's elements overrun its word count.".to_string())); + "InlineComposite list's elements overrun its word count.".to_string(), + )); } if words_per_element == 0 { @@ -2143,12 +2514,15 @@ mod wire_helpers { None | Some(Void) | Some(InlineComposite) => (), Some(Bit) => { return Err(Error::failed( - "Found struct list where bit list was expected.".to_string())); + "Found struct list where bit list was expected.".to_string(), + )); } Some(Byte) | Some(TwoBytes) | Some(FourBytes) | Some(EightBytes) => { if data_size == 0 { return Err(Error::failed( - "Expected a primitive list, but got a list of pointer-only structs".to_string())); + "Expected a primitive list, but got a list of pointer-only structs" + .to_string(), + )); } } Some(Pointer) => { @@ -2158,7 +2532,9 @@ mod wire_helpers { ptr = ptr.offset(data_size as isize * BYTES_PER_WORD as isize); if ptr_count == 0 { return Err(Error::failed( - "Expected a pointer list, but got a list of data-only structs".to_string())); + "Expected a pointer list, but got a list of data-only structs" + .to_string(), + )); } } } @@ -2187,7 +2563,12 @@ mod wire_helpers { let word_count = round_bits_up_to_words(u64::from(element_count) * u64::from(step)); bounds_check( - arena, segment_id, ptr, word_count as usize, WirePointerKind::List)?; + arena, + segment_id, + ptr, + word_count as usize, + WirePointerKind::List, + )?; if element_size == Void { // Watch out for lists of void, which can claim to be arbitrarily large @@ -2196,7 +2577,8 @@ mod wire_helpers { } if let Some(expected_element_size) = expected_element_size { - if element_size == ElementSize::Bit && expected_element_size != ElementSize::Bit { + if element_size == ElementSize::Bit && expected_element_size != ElementSize::Bit + { return Err(Error::failed( "Found bit list where struct list was expected; upgrade boolean lists to\ structs is no longer supported".to_string())); @@ -2207,14 +2589,17 @@ mod wire_helpers { // checking will be performed at field access time. So this check here is for the // case where we expected a list of some primitive or pointer type. - let expected_data_bits_per_element = data_bits_per_element(expected_element_size); + let expected_data_bits_per_element = + data_bits_per_element(expected_element_size); let expected_pointers_per_element = pointers_per_element(expected_element_size); - if expected_data_bits_per_element > data_size || - expected_pointers_per_element > pointer_count { - return Err(Error::failed( - "Message contains list with incompatible element type.".to_string())); - } + if expected_data_bits_per_element > data_size + || expected_pointers_per_element > pointer_count + { + return Err(Error::failed( + "Message contains list with incompatible element type.".to_string(), + )); + } } Ok(ListReader { @@ -2238,8 +2623,8 @@ mod wire_helpers { mut arena: &'a dyn ReaderArena, mut segment_id: u32, mut reff: *const WirePointer, - default: Option<&[crate::Word]>) -> Result> - { + default: Option<&[crate::Word]>, + ) -> Result> { if (*reff).is_null() { match default { None => return Ok(""), @@ -2256,30 +2641,39 @@ mod wire_helpers { if (*reff).kind() != WirePointerKind::List { return Err(Error::failed( - "Message contains non-list pointer where text was expected.".to_string())); + "Message contains non-list pointer where text was expected.".to_string(), + )); } if (*reff).list_element_size() != Byte { return Err(Error::failed( - "Message contains list pointer of non-bytes where text was expected.".to_string())); + "Message contains list pointer of non-bytes where text was expected.".to_string(), + )); } - bounds_check(arena, segment_id, ptr, - round_bytes_up_to_words(size) as usize, - WirePointerKind::List)?; + bounds_check( + arena, + segment_id, + ptr, + round_bytes_up_to_words(size) as usize, + WirePointerKind::List, + )?; if size == 0 { - return Err(Error::failed("Message contains text that is not NUL-terminated.".to_string())); + return Err(Error::failed( + "Message contains text that is not NUL-terminated.".to_string(), + )); } let str_ptr = ptr as *const u8; if (*str_ptr.offset((size - 1) as isize)) != 0u8 { return Err(Error::failed( - "Message contains text that is not NUL-terminated".to_string())); + "Message contains text that is not NUL-terminated".to_string(), + )); } - text::new_reader(slice::from_raw_parts(str_ptr, size as usize -1)) + text::new_reader(slice::from_raw_parts(str_ptr, size as usize - 1)) } #[inline] @@ -2287,8 +2681,8 @@ mod wire_helpers { mut arena: &'a dyn ReaderArena, mut segment_id: u32, mut reff: *const WirePointer, - default: Option<&'a [crate::Word]>) -> Result> - { + default: Option<&'a [crate::Word]>, + ) -> Result> { if (*reff).is_null() { match default { None => return Ok(&[]), @@ -2306,24 +2700,32 @@ mod wire_helpers { if (*reff).kind() != WirePointerKind::List { return Err(Error::failed( - "Message contains non-list pointer where data was expected.".to_string())); + "Message contains non-list pointer where data was expected.".to_string(), + )); } if (*reff).list_element_size() != Byte { return Err(Error::failed( - "Message contains list pointer of non-bytes where data was expected.".to_string())); + "Message contains list pointer of non-bytes where data was expected.".to_string(), + )); } - bounds_check(arena, segment_id, ptr, - round_bytes_up_to_words(size) as usize, - WirePointerKind::List)?; + bounds_check( + arena, + segment_id, + ptr, + round_bytes_up_to_words(size) as usize, + WirePointerKind::List, + )?; Ok(data::reader_from_raw_parts(ptr as *const _, size)) } } static ZERO: u64 = 0; -fn zero_pointer() -> *const WirePointer { &ZERO as *const _ as *const _ } +fn zero_pointer() -> *const WirePointer { + &ZERO as *const _ as *const _ +} static NULL_ARENA: NullArena = NullArena; @@ -2334,7 +2736,6 @@ pub enum CapTableReader { // At one point, we had a `Dummy` variant here, but that ended up // making values of this type take 16 bytes of memory. Now we instead // represent a null CapTableReader with `Plain(ptr::null())`. - Plain(*const Vec>>), } @@ -2342,13 +2743,16 @@ impl CapTableReader { pub fn extract_cap(&self, index: usize) -> Option> { match *self { CapTableReader::Plain(hooks) => { - if hooks.is_null() { return None } + if hooks.is_null() { + return None; + } let hooks: &Vec>> = unsafe { &*hooks }; - if index >= hooks.len() { None } - else { + if index >= hooks.len() { + None + } else { match hooks[index] { None => None, - Some(ref hook) => Some(hook.add_ref()) + Some(ref hook) => Some(hook.add_ref()), } } } @@ -2361,7 +2765,6 @@ pub enum CapTableBuilder { // At one point, we had a `Dummy` variant here, but that ended up // making values of this type take 16 bytes of memory. Now we instead // represent a null CapTableBuilder with `Plain(ptr::null_mut())`. - Plain(*mut Vec>>), } @@ -2375,13 +2778,16 @@ impl CapTableBuilder { pub fn extract_cap(&self, index: usize) -> Option> { match *self { CapTableBuilder::Plain(hooks) => { - if hooks.is_null() { return None } + if hooks.is_null() { + return None; + } let hooks: &Vec>> = unsafe { &*hooks }; - if index >= hooks.len() { None } - else { + if index >= hooks.len() { + None + } else { match hooks[index] { None => None, - Some(ref hook) => Some(hook.add_ref()) + Some(ref hook) => Some(hook.add_ref()), } } } @@ -2392,8 +2798,10 @@ impl CapTableBuilder { match *self { CapTableBuilder::Plain(hooks) => { if hooks.is_null() { - panic!("Called inject_cap() on a null capability table. You need \ - to call imbue_mut() on this message before adding capabilities."); + panic!( + "Called inject_cap() on a null capability table. You need \ + to call imbue_mut() on this message before adding capabilities." + ); } let hooks: &mut Vec>> = unsafe { &mut *hooks }; hooks.push(Some(cap)); @@ -2406,19 +2814,22 @@ impl CapTableBuilder { match *self { CapTableBuilder::Plain(hooks) => { if hooks.is_null() { - panic!("Called drop_cap() on a null capability table. You need \ - to call imbue_mut() on this message before adding capabilities."); + panic!( + "Called drop_cap() on a null capability table. You need \ + to call imbue_mut() on this message before adding capabilities." + ); } let hooks: &mut Vec>> = unsafe { &mut *hooks }; - if index < hooks.len() { hooks[index] = None; } + if index < hooks.len() { + hooks[index] = None; + } } } } } - #[derive(Clone, Copy)] -pub struct PointerReader<'a> { +pub struct PointerReader<'a> { arena: &'a dyn ReaderArena, cap_table: CapTableReader, pointer: *const WirePointer, @@ -2426,24 +2837,30 @@ pub struct PointerReader<'a> { nesting_limit: i32, } -impl <'a> PointerReader<'a> { +impl<'a> PointerReader<'a> { pub fn new_default<'b>() -> PointerReader<'b> { PointerReader { arena: &NULL_ARENA, segment_id: 0, cap_table: CapTableReader::Plain(ptr::null()), pointer: ptr::null(), - nesting_limit: 0x7fffffff } + nesting_limit: 0x7fffffff, + } } - pub fn get_root(arena: &'a dyn ReaderArena, - segment_id: u32, - location: *const u8, - nesting_limit: i32) -> Result - { - wire_helpers::bounds_check(arena, segment_id, location as *const _, - POINTER_SIZE_IN_WORDS, - WirePointerKind::Struct)?; + pub fn get_root( + arena: &'a dyn ReaderArena, + segment_id: u32, + location: *const u8, + nesting_limit: i32, + ) -> Result { + wire_helpers::bounds_check( + arena, + segment_id, + location as *const _, + POINTER_SIZE_IN_WORDS, + WirePointerKind::Struct, + )?; Ok(PointerReader { arena, @@ -2455,7 +2872,10 @@ impl <'a> PointerReader<'a> { } pub fn reborrow(&self) -> PointerReader<'_> { - PointerReader { arena: self.arena, .. *self } + PointerReader { + arena: self.arena, + ..*self + } } pub fn get_root_unchecked<'b>(location: *const u8) -> PointerReader<'b> { @@ -2464,7 +2884,8 @@ impl <'a> PointerReader<'a> { segment_id: 0, cap_table: CapTableReader::Plain(ptr::null()), pointer: location as *const _, - nesting_limit: 0x7fffffff } + nesting_limit: 0x7fffffff, + } } pub fn imbue(&mut self, cap_table: CapTableReader) { @@ -2478,25 +2899,54 @@ impl <'a> PointerReader<'a> { pub fn total_size(&self) -> Result { if self.pointer.is_null() { - Ok( MessageSize { word_count: 0, cap_count: 0 } ) + Ok(MessageSize { + word_count: 0, + cap_count: 0, + }) } else { - unsafe { wire_helpers::total_size(self.arena, self.segment_id, self.pointer, self.nesting_limit) } + unsafe { + wire_helpers::total_size( + self.arena, + self.segment_id, + self.pointer, + self.nesting_limit, + ) + } } } pub fn get_struct(self, default: Option<&'a [crate::Word]>) -> Result> { - let reff: *const WirePointer = if self.pointer.is_null() { zero_pointer() } else { self.pointer }; + let reff: *const WirePointer = if self.pointer.is_null() { + zero_pointer() + } else { + self.pointer + }; unsafe { - wire_helpers::read_struct_pointer(self.arena, - self.segment_id, self.cap_table, reff, - default, self.nesting_limit) + wire_helpers::read_struct_pointer( + self.arena, + self.segment_id, + self.cap_table, + reff, + default, + self.nesting_limit, + ) } } - pub fn get_list(self, expected_element_size: ElementSize, - default: Option<&'a [crate::Word]>) -> Result> { - let default_value: *const u8 = match default { None => core::ptr::null(), Some(d) => d.as_ptr() as *const u8}; - let reff = if self.pointer.is_null() { zero_pointer() } else { self.pointer }; + pub fn get_list( + self, + expected_element_size: ElementSize, + default: Option<&'a [crate::Word]>, + ) -> Result> { + let default_value: *const u8 = match default { + None => core::ptr::null(), + Some(d) => d.as_ptr() as *const u8, + }; + let reff = if self.pointer.is_null() { + zero_pointer() + } else { + self.pointer + }; unsafe { wire_helpers::read_list_pointer( self.arena, @@ -2504,12 +2954,18 @@ impl <'a> PointerReader<'a> { self.cap_table, reff, default_value, - Some(expected_element_size), self.nesting_limit) + Some(expected_element_size), + self.nesting_limit, + ) } } fn get_list_any_size(self, default_value: *const u8) -> Result> { - let reff = if self.pointer.is_null() { zero_pointer() } else { self.pointer }; + let reff = if self.pointer.is_null() { + zero_pointer() + } else { + self.pointer + }; unsafe { wire_helpers::read_list_pointer( self.arena, @@ -2517,29 +2973,44 @@ impl <'a> PointerReader<'a> { self.cap_table, reff, default_value, - None, self.nesting_limit) + None, + self.nesting_limit, + ) } } pub fn get_text(self, default: Option<&[crate::Word]>) -> Result> { - let reff = if self.pointer.is_null() { zero_pointer() } else { self.pointer }; - unsafe { - wire_helpers::read_text_pointer(self.arena, self.segment_id, reff, default) - } + let reff = if self.pointer.is_null() { + zero_pointer() + } else { + self.pointer + }; + unsafe { wire_helpers::read_text_pointer(self.arena, self.segment_id, reff, default) } } pub fn get_data(&self, default: Option<&'a [crate::Word]>) -> Result> { - let reff = if self.pointer.is_null() { zero_pointer() } else { self.pointer }; - unsafe { - wire_helpers::read_data_pointer(self.arena, self.segment_id, reff, default) - } + let reff = if self.pointer.is_null() { + zero_pointer() + } else { + self.pointer + }; + unsafe { wire_helpers::read_data_pointer(self.arena, self.segment_id, reff, default) } } pub fn get_capability(&self) -> Result> { - let reff: *const WirePointer = if self.pointer.is_null() { zero_pointer() } else { self.pointer }; + let reff: *const WirePointer = if self.pointer.is_null() { + zero_pointer() + } else { + self.pointer + }; unsafe { wire_helpers::read_capability_pointer( - self.arena, self.segment_id, self.cap_table, reff, self.nesting_limit) + self.arena, + self.segment_id, + self.cap_table, + reff, + self.nesting_limit, + ) } } @@ -2547,13 +3018,13 @@ impl <'a> PointerReader<'a> { if self.is_null() { Ok(PointerType::Null) } else { - let (_, reff, _) = unsafe { - wire_helpers::follow_fars(self.arena, self.pointer, self.segment_id)? - }; + let (_, reff, _) = + unsafe { wire_helpers::follow_fars(self.arena, self.pointer, self.segment_id)? }; match unsafe { (*reff).kind() } { - WirePointerKind::Far => - Err(crate::Error::failed(String::from("Unexpected FAR pointer"))), + WirePointerKind::Far => { + Err(crate::Error::failed(String::from("Unexpected FAR pointer"))) + } WirePointerKind::Struct => Ok(PointerType::Struct), WirePointerKind::List => Ok(PointerType::List), WirePointerKind::Other => { @@ -2569,7 +3040,7 @@ impl <'a> PointerReader<'a> { pub fn is_canonical(&self, read_head: &Cell<*const u8>) -> Result { if self.pointer.is_null() || unsafe { !(*self.pointer).is_positional() } { - return Ok(false) + return Ok(false); } match self.get_pointer_type()? { @@ -2581,13 +3052,14 @@ impl <'a> PointerReader<'a> { if st.get_data_section_size() == 0 && st.get_pointer_section_size() == 0 { Ok(self.pointer as *const _ == st.get_location()) } else { - let result = st.is_canonical(read_head, read_head, &mut data_trunc, &mut ptr_trunc)?; + let result = + st.is_canonical(read_head, read_head, &mut data_trunc, &mut ptr_trunc)?; Ok(result && data_trunc && ptr_trunc) } } - PointerType::List => { - self.get_list_any_size(ptr::null())?.is_canonical(read_head, self.pointer) - } + PointerType::List => self + .get_list_any_size(ptr::null())? + .is_canonical(read_head, self.pointer), PointerType::Capability => Ok(false), } } @@ -2598,17 +3070,12 @@ pub struct PointerBuilder<'a> { arena: &'a dyn BuilderArena, segment_id: u32, cap_table: CapTableBuilder, - pointer: *mut WirePointer + pointer: *mut WirePointer, } -impl <'a> PointerBuilder<'a> { +impl<'a> PointerBuilder<'a> { #[inline] - pub fn get_root( - arena: &'a dyn BuilderArena, - segment_id: u32, - location: *mut u8) - -> Self - { + pub fn get_root(arena: &'a dyn BuilderArena, segment_id: u32, location: *mut u8) -> Self { PointerBuilder { arena, cap_table: CapTableBuilder::Plain(ptr::null_mut()), @@ -2618,7 +3085,10 @@ impl <'a> PointerBuilder<'a> { } pub fn reborrow(&mut self) -> PointerBuilder<'_> { - PointerBuilder { arena: self.arena, .. *self } + PointerBuilder { + arena: self.arena, + ..*self + } } pub fn imbue(&mut self, cap_table: CapTableBuilder) { @@ -2630,7 +3100,11 @@ impl <'a> PointerBuilder<'a> { unsafe { (*self.pointer).is_null() } } - pub fn get_struct(self, size: StructSize, default: Option<&'a [crate::Word]>) -> Result> { + pub fn get_struct( + self, + size: StructSize, + default: Option<&'a [crate::Word]>, + ) -> Result> { unsafe { wire_helpers::get_writable_struct_pointer( self.arena, @@ -2638,45 +3112,72 @@ impl <'a> PointerBuilder<'a> { self.segment_id, self.cap_table, size, - default) + default, + ) } } - pub fn get_list(self, element_size: ElementSize, default: Option<&'a [crate::Word]>) - -> Result> - { - let default_value: *const u8 = match default { None => core::ptr::null(), Some(d) => d.as_ptr() as *const u8}; + pub fn get_list( + self, + element_size: ElementSize, + default: Option<&'a [crate::Word]>, + ) -> Result> { + let default_value: *const u8 = match default { + None => core::ptr::null(), + Some(d) => d.as_ptr() as *const u8, + }; unsafe { wire_helpers::get_writable_list_pointer( - self.arena, self.pointer, self.segment_id, self.cap_table, element_size, default_value) + self.arena, + self.pointer, + self.segment_id, + self.cap_table, + element_size, + default_value, + ) } } - pub fn get_struct_list(self, element_size: StructSize, - default: Option<&'a [crate::Word]>) -> Result> - { - let default_value: *const u8 = match default { None => core::ptr::null(), Some(d) => d.as_ptr() as *const u8}; + pub fn get_struct_list( + self, + element_size: StructSize, + default: Option<&'a [crate::Word]>, + ) -> Result> { + let default_value: *const u8 = match default { + None => core::ptr::null(), + Some(d) => d.as_ptr() as *const u8, + }; unsafe { wire_helpers::get_writable_struct_list_pointer( - self.arena, self.pointer, self.segment_id, self.cap_table, element_size, default_value) + self.arena, + self.pointer, + self.segment_id, + self.cap_table, + element_size, + default_value, + ) } } - pub fn get_text(self, default: Option<&'a [crate::Word]>) -> Result> - { + pub fn get_text(self, default: Option<&'a [crate::Word]>) -> Result> { unsafe { wire_helpers::get_writable_text_pointer( self.arena, - self.pointer, self.segment_id, default) + self.pointer, + self.segment_id, + default, + ) } } - pub fn get_data(self, default: Option<&'a [crate::Word]>) - -> Result> - { + pub fn get_data(self, default: Option<&'a [crate::Word]>) -> Result> { unsafe { wire_helpers::get_writable_data_pointer( - self.arena, self.pointer, self.segment_id, default) + self.arena, + self.pointer, + self.segment_id, + default, + ) } } @@ -2684,30 +3185,57 @@ impl <'a> PointerBuilder<'a> { unsafe { wire_helpers::read_capability_pointer( self.arena.as_reader(), - self.segment_id, self.cap_table.into_reader(), self.pointer, ::core::i32::MAX) + self.segment_id, + self.cap_table.into_reader(), + self.pointer, + ::core::i32::MAX, + ) } } pub fn init_struct(self, size: StructSize) -> StructBuilder<'a> { unsafe { - wire_helpers::init_struct_pointer(self.arena, self.pointer, self.segment_id, self.cap_table, size) + wire_helpers::init_struct_pointer( + self.arena, + self.pointer, + self.segment_id, + self.cap_table, + size, + ) } } - pub fn init_list(self, element_size: ElementSize, element_count: ElementCount32) -> ListBuilder<'a> { + pub fn init_list( + self, + element_size: ElementSize, + element_count: ElementCount32, + ) -> ListBuilder<'a> { unsafe { wire_helpers::init_list_pointer( - self.arena, self.pointer, self.segment_id, self.cap_table, element_count, element_size) + self.arena, + self.pointer, + self.segment_id, + self.cap_table, + element_count, + element_size, + ) } } - pub fn init_struct_list(self, element_count: ElementCount32, element_size: StructSize) - -> ListBuilder<'a> { + pub fn init_struct_list( + self, + element_count: ElementCount32, + element_size: StructSize, + ) -> ListBuilder<'a> { unsafe { wire_helpers::init_struct_list_pointer( self.arena, - self.pointer, self.segment_id, - self.cap_table, element_count, element_size) + self.pointer, + self.segment_id, + self.cap_table, + element_count, + element_size, + ) } } @@ -2727,15 +3255,26 @@ impl <'a> PointerBuilder<'a> { unsafe { wire_helpers::set_struct_pointer( self.arena, - self.segment_id, self.cap_table, self.pointer, *value, canonicalize)?; + self.segment_id, + self.cap_table, + self.pointer, + *value, + canonicalize, + )?; Ok(()) } } pub fn set_list(&self, value: &ListReader, canonicalize: bool) -> Result<()> { unsafe { - wire_helpers::set_list_pointer(self.arena, self.segment_id, - self.cap_table, self.pointer, *value, canonicalize)?; + wire_helpers::set_list_pointer( + self.arena, + self.segment_id, + self.cap_table, + self.pointer, + *value, + canonicalize, + )?; Ok(()) } } @@ -2754,11 +3293,16 @@ impl <'a> PointerBuilder<'a> { pub fn set_capability(&self, cap: Box) { wire_helpers::set_capability_pointer( - self.arena, self.segment_id, self.cap_table, self.pointer, cap); + self.arena, + self.segment_id, + self.cap_table, + self.pointer, + cap, + ); } pub fn copy_from(&mut self, other: PointerReader, canonicalize: bool) -> Result<()> { - if other.pointer.is_null() { + if other.pointer.is_null() { if !self.pointer.is_null() { unsafe { wire_helpers::zero_object(self.arena, self.segment_id, self.pointer); @@ -2767,10 +3311,18 @@ impl <'a> PointerBuilder<'a> { } } else { unsafe { - wire_helpers::copy_pointer(self.arena, self.segment_id, self.cap_table, self.pointer, - other.arena, - other.segment_id, other.cap_table, other.pointer, - other.nesting_limit, canonicalize)?; + wire_helpers::copy_pointer( + self.arena, + self.segment_id, + self.cap_table, + self.pointer, + other.arena, + other.segment_id, + other.cap_table, + other.pointer, + other.nesting_limit, + canonicalize, + )?; } } Ok(()) @@ -2789,7 +3341,7 @@ impl <'a> PointerBuilder<'a> { segment_id: self.segment_id, cap_table: self.cap_table.into_reader(), pointer: self.pointer, - nesting_limit: 0x7fffffff + nesting_limit: 0x7fffffff, } } } @@ -2806,7 +3358,7 @@ pub struct StructReader<'a> { nesting_limit: i32, } -impl <'a> StructReader<'a> { +impl<'a> StructReader<'a> { pub fn new_default<'b>() -> StructReader<'b> { StructReader { arena: &NULL_ARENA, @@ -2816,16 +3368,21 @@ impl <'a> StructReader<'a> { pointers: ptr::null(), data_size: 0, pointer_count: 0, - nesting_limit: 0x7fffffff} + nesting_limit: 0x7fffffff, + } } pub fn imbue(&mut self, cap_table: CapTableReader) { self.cap_table = cap_table } - pub fn get_data_section_size(&self) -> BitCount32 { self.data_size } + pub fn get_data_section_size(&self) -> BitCount32 { + self.data_size + } - pub fn get_pointer_section_size(&self) -> WirePointerCount16 { self.pointer_count } + pub fn get_pointer_section_size(&self) -> WirePointerCount16 { + self.pointer_count + } pub fn get_pointer_section_as_list(&self) -> ListReader<'a> { ListReader { @@ -2861,9 +3418,7 @@ impl <'a> StructReader<'a> { // not contain the field. if (offset + 1) * bits_per_element::() <= self.data_size as usize { let dwv: *const ::Raw = self.data as *const _; - unsafe { - ::get(&*dwv.add(offset)) - } + unsafe { ::get(&*dwv.add(offset)) } } else { T::zero() } @@ -2883,17 +3438,17 @@ impl <'a> StructReader<'a> { } #[inline] - pub fn get_data_field_mask(&self, - offset: ElementCount, - mask: ::T) -> T { + pub fn get_data_field_mask( + &self, + offset: ElementCount, + mask: ::T, + ) -> T { Mask::mask(self.get_data_field(offset), mask) } #[inline] - pub fn get_bool_field_mask(&self, - offset: ElementCount, - mask: bool) -> bool { - self.get_bool_field(offset) ^ mask + pub fn get_bool_field_mask(&self, offset: ElementCount, mask: bool) -> bool { + self.get_bool_field(offset) ^ mask } #[inline] @@ -2904,7 +3459,7 @@ impl <'a> StructReader<'a> { segment_id: self.segment_id, cap_table: self.cap_table, pointer: unsafe { self.pointers.add(ptr_index) }, - nesting_limit: self.nesting_limit + nesting_limit: self.nesting_limit, } } else { PointerReader::new_default() @@ -2913,15 +3468,20 @@ impl <'a> StructReader<'a> { pub fn total_size(&self) -> Result { let mut result = MessageSize { - word_count: u64::from(wire_helpers::round_bits_up_to_words(u64::from(self.data_size))) + - u64::from(self.pointer_count) * WORDS_PER_POINTER as u64, - cap_count: 0 }; + word_count: u64::from(wire_helpers::round_bits_up_to_words(u64::from( + self.data_size, + ))) + u64::from(self.pointer_count) * WORDS_PER_POINTER as u64, + cap_count: 0, + }; - for i in 0.. self.pointer_count as isize { + for i in 0..self.pointer_count as isize { unsafe { result += wire_helpers::total_size( - self.arena, self.segment_id, self.pointers.offset(i), - self.nesting_limit)?; + self.arena, + self.segment_id, + self.pointers.offset(i), + self.nesting_limit, + )?; } } @@ -2940,16 +3500,14 @@ impl <'a> StructReader<'a> { ptr_head: &Cell<*const u8>, data_trunc: &mut bool, ptr_trunc: &mut bool, - ) - -> Result - { + ) -> Result { if self.get_location() != read_head.get() { - return Ok(false) + return Ok(false); } if self.get_data_section_size() % BITS_PER_WORD as u32 != 0 { // legacy non-word-size struct - return Ok(false) + return Ok(false); } let data_size = self.get_data_section_size() / BITS_PER_WORD as u32; @@ -2962,17 +3520,25 @@ impl <'a> StructReader<'a> { } if self.pointer_count != 0 { - *ptr_trunc = !self.get_pointer_field(self.pointer_count as usize - 1).is_null(); + *ptr_trunc = !self + .get_pointer_field(self.pointer_count as usize - 1) + .is_null(); } else { *ptr_trunc = true; } - read_head.set( - unsafe { (read_head.get()).offset((data_size as isize + self.pointer_count as isize) * (BYTES_PER_WORD as isize)) }); + read_head.set(unsafe { + (read_head.get()).offset( + (data_size as isize + self.pointer_count as isize) * (BYTES_PER_WORD as isize), + ) + }); for ptr_idx in 0..self.pointer_count { - if !self.get_pointer_field(ptr_idx as usize).is_canonical(ptr_head)? { - return Ok(false) + if !self + .get_pointer_field(ptr_idx as usize) + .is_canonical(ptr_head)? + { + return Ok(false); } } @@ -2991,7 +3557,7 @@ pub struct StructBuilder<'a> { pointer_count: WirePointerCount16, } -impl <'a> StructBuilder<'a> { +impl<'a> StructBuilder<'a> { pub fn into_reader(self) -> StructReader<'a> { StructReader { arena: self.arena.as_reader(), @@ -3010,77 +3576,70 @@ impl <'a> StructBuilder<'a> { } #[inline] - pub fn set_data_field(&self, offset: ElementCount, value: T) { + pub fn set_data_field(&self, offset: ElementCount, value: T) { let ptr: *mut ::Raw = self.data as *mut _; - unsafe { - ::set(&mut*ptr.add(offset), value) - } + unsafe { ::set(&mut *ptr.add(offset), value) } } #[inline] - pub fn set_data_field_mask(&self, - offset: ElementCount, - value: T, - mask: ::T) { + pub fn set_data_field_mask( + &self, + offset: ElementCount, + value: T, + mask: ::T, + ) { self.set_data_field(offset, Mask::mask(value, mask)); } #[inline] pub fn get_data_field(&self, offset: ElementCount) -> T { let ptr: *const ::Raw = self.data as *const _; - unsafe { - ::get(&*ptr.add(offset)) - } + unsafe { ::get(&*ptr.add(offset)) } } #[inline] - pub fn get_data_field_mask(&self, - offset: ElementCount, - mask: ::T) -> T { + pub fn get_data_field_mask( + &self, + offset: ElementCount, + mask: ::T, + ) -> T { Mask::mask(self.get_data_field(offset), mask) } - #[inline] pub fn set_bool_field(&self, offset: ElementCount, value: bool) { //# This branch should be compiled out whenever this is //# inlined with a constant offset. let boffset: BitCount0 = offset; - let b = unsafe { self.data.add(boffset / BITS_PER_BYTE)}; + let b = unsafe { self.data.add(boffset / BITS_PER_BYTE) }; let bitnum = boffset % BITS_PER_BYTE; - unsafe { (*b) = ( (*b) & !(1 << bitnum)) | (u8::from(value) << bitnum) } + unsafe { (*b) = ((*b) & !(1 << bitnum)) | (u8::from(value) << bitnum) } } #[inline] - pub fn set_bool_field_mask(&self, - offset: ElementCount, - value: bool, - mask: bool) { - self.set_bool_field(offset , value ^ mask); + pub fn set_bool_field_mask(&self, offset: ElementCount, value: bool, mask: bool) { + self.set_bool_field(offset, value ^ mask); } #[inline] pub fn get_bool_field(&self, offset: ElementCount) -> bool { let boffset: BitCount0 = offset; let b = unsafe { self.data.add(boffset / BITS_PER_BYTE) }; - unsafe { ((*b) & (1 << (boffset % BITS_PER_BYTE ))) != 0 } + unsafe { ((*b) & (1 << (boffset % BITS_PER_BYTE))) != 0 } } #[inline] - pub fn get_bool_field_mask(&self, - offset: ElementCount, - mask: bool) -> bool { - self.get_bool_field(offset) ^ mask + pub fn get_bool_field_mask(&self, offset: ElementCount, mask: bool) -> bool { + self.get_bool_field(offset) ^ mask } - #[inline] pub fn get_pointer_field(self, ptr_index: WirePointerCount) -> PointerBuilder<'a> { PointerBuilder { arena: self.arena, segment_id: self.segment_id, cap_table: self.cap_table, - pointer: unsafe { self.pointers.add(ptr_index) } + pointer: unsafe { self.pointers.add(ptr_index) }, } } @@ -3090,17 +3649,21 @@ impl <'a> StructBuilder<'a> { let shared_data_size = min(self.data_size, other.data_size); let shared_pointer_count = min(self.pointer_count, other.pointer_count); - if (shared_data_size > 0 && other.data == self.data) || - (shared_pointer_count > 0 && other.pointers == self.pointers) { + if (shared_data_size > 0 && other.data == self.data) + || (shared_pointer_count > 0 && other.pointers == self.pointers) + { // At least one of the section pointers is pointing to ourself. Verify that the other is too // (but ignore empty sections). - if (shared_data_size == 0 || other.data == self.data) && - (shared_pointer_count == 0 || other.pointers == self.pointers) { - return Err(crate::Error::failed(String::from("Only one of the section pointers is pointing to ourself"))) + if (shared_data_size == 0 || other.data == self.data) + && (shared_pointer_count == 0 || other.pointers == self.pointers) + { + return Err(crate::Error::failed(String::from( + "Only one of the section pointers is pointing to ourself", + ))); } // So `other` appears to be a reader for this same struct. No copying is needed. - return Ok(()) + return Ok(()); } unsafe { @@ -3110,8 +3673,14 @@ impl <'a> StructBuilder<'a> { if self.data_size == 1 { self.set_bool_field(0, false); } else { - let unshared = self.data.offset((shared_data_size / BITS_PER_BYTE as u32) as isize); - ptr::write_bytes(unshared, 0, ((self.data_size - shared_data_size) / BITS_PER_BYTE as u32) as usize); + let unshared = self + .data + .offset((shared_data_size / BITS_PER_BYTE as u32) as isize); + ptr::write_bytes( + unshared, + 0, + ((self.data_size - shared_data_size) / BITS_PER_BYTE as u32) as usize, + ); } } @@ -3119,26 +3688,36 @@ impl <'a> StructBuilder<'a> { if shared_data_size == 1 { self.set_bool_field(0, other.get_bool_field(0)); } else { - ptr::copy_nonoverlapping(other.data, self.data, (shared_data_size / BITS_PER_BYTE as u32) as usize); + ptr::copy_nonoverlapping( + other.data, + self.data, + (shared_data_size / BITS_PER_BYTE as u32) as usize, + ); } // Zero out all pointers in the target. for i in 0..self.pointer_count as isize { - wire_helpers::zero_object(self.arena, self.segment_id, self.pointers.offset(i) as *mut _); + wire_helpers::zero_object( + self.arena, + self.segment_id, + self.pointers.offset(i) as *mut _, + ); } ptr::write_bytes(self.pointers, 0u8, self.pointer_count as usize); for i in 0..shared_pointer_count as isize { - wire_helpers::copy_pointer(self.arena, - self.segment_id, - self.cap_table, - self.pointers.offset(i), - other.arena, - other.segment_id, - other.cap_table, - other.pointers.offset(i), - other.nesting_limit, - false)?; + wire_helpers::copy_pointer( + self.arena, + self.segment_id, + self.cap_table, + self.pointers.offset(i), + other.arena, + other.segment_id, + other.cap_table, + other.pointers.offset(i), + other.nesting_limit, + false, + )?; } } @@ -3160,7 +3739,7 @@ pub struct ListReader<'a> { element_size: ElementSize, } -impl <'a> ListReader<'a> { +impl<'a> ListReader<'a> { pub fn new_default<'b>() -> ListReader<'b> { ListReader { arena: &NULL_ARENA, @@ -3181,7 +3760,9 @@ impl <'a> ListReader<'a> { } #[inline] - pub fn len(&self) -> ElementCount32 { self.element_count } + pub fn len(&self) -> ElementCount32 { + self.element_count + } pub(crate) fn get_step_size_in_bits(&self) -> u32 { self.step @@ -3198,10 +3779,9 @@ impl <'a> ListReader<'a> { &[] } else { let num_bytes = wire_helpers::round_bits_up_to_bytes( - u64::from(self.step) * u64::from(self.element_count)) as usize; - unsafe { - ::core::slice::from_raw_parts(self.ptr, num_bytes) - } + u64::from(self.step) * u64::from(self.element_count), + ) as usize; + unsafe { ::core::slice::from_raw_parts(self.ptr, num_bytes) } } } @@ -3212,9 +3792,8 @@ impl <'a> ListReader<'a> { let struct_data: *const u8 = unsafe { self.ptr.offset(index_byte as isize) }; - let struct_pointers: *const WirePointer = unsafe { - struct_data.add(self.struct_data_size as usize / BITS_PER_BYTE) as *const _ - }; + let struct_pointers: *const WirePointer = + unsafe { struct_data.add(self.struct_data_size as usize / BITS_PER_BYTE) as *const _ }; StructReader { arena: self.arena, @@ -3236,47 +3815,51 @@ impl <'a> ListReader<'a> { segment_id: self.segment_id, cap_table: self.cap_table, pointer: unsafe { self.ptr.offset(offset as isize) } as *const _, - nesting_limit: self.nesting_limit + nesting_limit: self.nesting_limit, } } pub fn is_canonical( &self, read_head: &Cell<*const u8>, - reff: *const WirePointer) - -> Result - { + reff: *const WirePointer, + ) -> Result { match self.element_size { ElementSize::InlineComposite => { read_head.set(unsafe { read_head.get().add(BYTES_PER_WORD) }); // tag word if self.ptr as *const _ != read_head.get() { - return Ok(false) + return Ok(false); } if self.struct_data_size % BITS_PER_WORD as u32 != 0 { - return Ok(false) + return Ok(false); } - let struct_size = (self.struct_data_size / BITS_PER_WORD as u32) + - u32::from(self.struct_pointer_count); + let struct_size = (self.struct_data_size / BITS_PER_WORD as u32) + + u32::from(self.struct_pointer_count); let word_count = unsafe { (*reff).list_inline_composite_word_count() }; if struct_size * self.element_count != word_count { - return Ok(false) + return Ok(false); } if struct_size == 0 { - return Ok(true) + return Ok(true); } - let list_end = - unsafe { read_head.get().add((self.element_count * struct_size) as usize * BYTES_PER_WORD) }; + let list_end = unsafe { + read_head + .get() + .add((self.element_count * struct_size) as usize * BYTES_PER_WORD) + }; let pointer_head = Cell::new(list_end); let mut list_data_trunc = false; let mut list_ptr_trunc = false; for idx in 0..self.element_count { let mut data_trunc = false; let mut ptr_trunc = false; - if !self.get_struct_element(idx).is_canonical(read_head, - &pointer_head, - &mut data_trunc, - &mut ptr_trunc)? { - return Ok(false) + if !self.get_struct_element(idx).is_canonical( + read_head, + &pointer_head, + &mut data_trunc, + &mut ptr_trunc, + )? { + return Ok(false); } list_data_trunc |= data_trunc; list_ptr_trunc |= ptr_trunc; @@ -3287,22 +3870,26 @@ impl <'a> ListReader<'a> { } ElementSize::Pointer => { if self.ptr as *const _ != read_head.get() { - return Ok(false) + return Ok(false); } read_head.set(unsafe { - read_head.get().offset(self.element_count as isize * BYTES_PER_WORD as isize) }); + read_head + .get() + .offset(self.element_count as isize * BYTES_PER_WORD as isize) + }); for idx in 0..self.element_count { if !self.get_pointer_element(idx).is_canonical(read_head)? { - return Ok(false) + return Ok(false); } } Ok(true) } element_size => { if self.ptr != read_head.get() as *const _ { - return Ok(false) + return Ok(false); } - let bit_size = u64::from(self.element_count) * u64::from(data_bits_per_element(element_size)); + let bit_size = + u64::from(self.element_count) * u64::from(data_bits_per_element(element_size)); let mut word_size = bit_size / BITS_PER_WORD as u64; if bit_size % BITS_PER_WORD as u64 != 0 { word_size += 1 @@ -3311,7 +3898,11 @@ impl <'a> ListReader<'a> { let byte_size = bit_size / BITS_PER_BYTE as u64; let mut byte_read_head: *const u8 = read_head.get() as *const u8; byte_read_head = unsafe { byte_read_head.offset(byte_size as isize) }; - let read_head_end = unsafe { read_head.get().offset(word_size as isize * BYTES_PER_WORD as isize) }; + let read_head_end = unsafe { + read_head + .get() + .offset(word_size as isize * BYTES_PER_WORD as isize) + }; let leftover_bits = bit_size % BITS_PER_BYTE as u64; if leftover_bits > 0 { @@ -3319,14 +3910,14 @@ impl <'a> ListReader<'a> { let partial_byte = unsafe { *byte_read_head }; if partial_byte & mask != 0 { - return Ok(false) + return Ok(false); } byte_read_head = unsafe { byte_read_head.offset(1_isize) }; } while byte_read_head != read_head_end as *const u8 { if unsafe { *byte_read_head } != 0 { - return Ok(false) + return Ok(false); } byte_read_head = unsafe { byte_read_head.offset(1_isize) }; } @@ -3351,8 +3942,7 @@ pub struct ListBuilder<'a> { element_size: ElementSize, } -impl <'a> ListBuilder<'a> { - +impl<'a> ListBuilder<'a> { #[inline] pub fn new_default<'b>() -> ListBuilder<'b> { ListBuilder { @@ -3384,7 +3974,10 @@ impl <'a> ListBuilder<'a> { } pub fn reborrow(&mut self) -> ListBuilder<'_> { - ListBuilder { arena: self.arena, ..*self } + ListBuilder { + arena: self.arena, + ..*self + } } pub fn imbue(&mut self, cap_table: CapTableBuilder) { @@ -3392,15 +3985,16 @@ impl <'a> ListBuilder<'a> { } #[inline] - pub fn len(&self) -> ElementCount32 { self.element_count } + pub fn len(&self) -> ElementCount32 { + self.element_count + } #[inline] pub fn get_struct_element(self, index: ElementCount32) -> StructBuilder<'a> { let index_byte = ((u64::from(index) * u64::from(self.step)) / BITS_PER_BYTE as u64) as u32; - let struct_data = unsafe{ self.ptr.offset(index_byte as isize)}; - let struct_pointers = unsafe { - struct_data.add((self.struct_data_size as usize) / BITS_PER_BYTE) as *mut _ - }; + let struct_data = unsafe { self.ptr.offset(index_byte as isize) }; + let struct_pointers = + unsafe { struct_data.add((self.struct_data_size as usize) / BITS_PER_BYTE) as *mut _ }; StructBuilder { arena: self.arena, segment_id: self.segment_id, @@ -3434,10 +4028,9 @@ impl <'a> ListBuilder<'a> { &mut [] } else { let num_bytes = wire_helpers::round_bits_up_to_bytes( - u64::from(self.step) * u64::from(self.element_count)) as usize; - unsafe { - ::core::slice::from_raw_parts_mut(self.ptr, num_bytes) - } + u64::from(self.step) * u64::from(self.element_count), + ) as usize; + unsafe { ::core::slice::from_raw_parts_mut(self.ptr, num_bytes) } } } } @@ -3459,7 +4052,7 @@ pub trait PrimitiveElement { fn element_size() -> ElementSize; } -impl PrimitiveElement for T { +impl PrimitiveElement for T { #[inline] fn get(list_reader: &ListReader, index: ElementCount32) -> Self { let offset = (u64::from(index) * u64::from(list_reader.step) / BITS_PER_BYTE as u64) as u32; @@ -3471,18 +4064,22 @@ impl PrimitiveElement for T { #[inline] fn get_from_builder(list_builder: &ListBuilder, index: ElementCount32) -> Self { - let offset = (u64::from(index) * u64::from(list_builder.step) / BITS_PER_BYTE as u64) as u32; + let offset = + (u64::from(index) * u64::from(list_builder.step) / BITS_PER_BYTE as u64) as u32; unsafe { - let ptr: *mut ::Raw = list_builder.ptr.offset(offset as isize) as *mut _; + let ptr: *mut ::Raw = + list_builder.ptr.offset(offset as isize) as *mut _; ::get(&*ptr) } } #[inline] fn set(list_builder: &ListBuilder, index: ElementCount32, value: Self) { - let offset = (u64::from(index) * u64::from(list_builder.step) / BITS_PER_BYTE as u64) as u32; + let offset = + (u64::from(index) * u64::from(list_builder.step) / BITS_PER_BYTE as u64) as u32; unsafe { - let ptr: *mut ::Raw = list_builder.ptr.offset(offset as isize) as *mut _; + let ptr: *mut ::Raw = + list_builder.ptr.offset(offset as isize) as *mut _; ::set(&mut *ptr, value); } } @@ -3512,7 +4109,7 @@ impl PrimitiveElement for bool { fn get_from_builder(list: &ListBuilder, index: ElementCount32) -> bool { let bindex = u64::from(index) * u64::from(list.step); let b = unsafe { list.ptr.offset((bindex / BITS_PER_BYTE as u64) as isize) }; - unsafe { ((*b) & (1 << (bindex % BITS_PER_BYTE as u64 ))) != 0 } + unsafe { ((*b) & (1 << (bindex % BITS_PER_BYTE as u64))) != 0 } } #[inline] fn set(list: &ListBuilder, index: ElementCount32, value: bool) { @@ -3522,18 +4119,22 @@ impl PrimitiveElement for bool { let bitnum = bindex % BITS_PER_BYTE as u64; unsafe { (*b) = ((*b) & !(1 << bitnum)) | (u8::from(value) << bitnum) } } - fn element_size() -> ElementSize { Bit } + fn element_size() -> ElementSize { + Bit + } } impl PrimitiveElement for () { #[inline] - fn get(_list: &ListReader, _index: ElementCount32) { } + fn get(_list: &ListReader, _index: ElementCount32) {} #[inline] - fn get_from_builder(_list: &ListBuilder, _index: ElementCount32) { } + fn get_from_builder(_list: &ListBuilder, _index: ElementCount32) {} #[inline] - fn set(_list: &ListBuilder, _index: ElementCount32, _value: ()) { } + fn set(_list: &ListBuilder, _index: ElementCount32, _value: ()) {} - fn element_size() -> ElementSize { Void } + fn element_size() -> ElementSize { + Void + } } diff --git a/capnp/src/private/layout_test.rs b/capnp/src/private/layout_test.rs index d8564f7b1..99eef10a8 100644 --- a/capnp/src/private/layout_test.rs +++ b/capnp/src/private/layout_test.rs @@ -22,16 +22,20 @@ use crate::private::layout::PointerReader; fn test_at_alignments(words: &[crate::Word], verify: &dyn Fn(PointerReader)) { - verify(PointerReader::get_root_unchecked(words.as_ptr() as *const u8)); + verify(PointerReader::get_root_unchecked( + words.as_ptr() as *const u8 + )); - #[cfg(feature="unaligned")] + #[cfg(feature = "unaligned")] { let mut unaligned_data = Vec::with_capacity((words.len() + 1) * 8); for offset in 0..8 { unaligned_data.clear(); unaligned_data.resize(offset, 0); unaligned_data.extend(crate::Word::words_to_bytes(words)); - verify(PointerReader::get_root_unchecked((unaligned_data[offset..]).as_ptr())); + verify(PointerReader::get_root_unchecked( + (unaligned_data[offset..]).as_ptr(), + )); } } } @@ -40,7 +44,8 @@ fn test_at_alignments(words: &[crate::Word], verify: &dyn Fn(PointerReader)) { fn simple_raw_data_struct() { let data: &[crate::Word] = &[ crate::word(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - crate::word(0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef)]; + crate::word(0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef), + ]; test_at_alignments(data, &verify); fn verify(reader: PointerReader) { @@ -58,7 +63,7 @@ fn simple_raw_data_struct() { assert_eq!(0xab89u16, reader.get_data_field::(2)); assert_eq!(0xefcdu16, reader.get_data_field::(3)); assert_eq!(0u16, reader.get_data_field::(4)); // past end of struct --> default value - // TODO the rest of uints. + // TODO the rest of uints. // Bits. assert_eq!(reader.get_bool_field(0), true); @@ -70,8 +75,8 @@ fn simple_raw_data_struct() { assert_eq!(reader.get_bool_field(6), false); assert_eq!(reader.get_bool_field(7), false); - assert_eq!(reader.get_bool_field(8), true); - assert_eq!(reader.get_bool_field(9), true); + assert_eq!(reader.get_bool_field(8), true); + assert_eq!(reader.get_bool_field(9), true); assert_eq!(reader.get_bool_field(10), false); assert_eq!(reader.get_bool_field(11), false); assert_eq!(reader.get_bool_field(12), false); @@ -92,14 +97,17 @@ fn bool_list() { let data: &[crate::Word] = &[ crate::word(0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00), - crate::word(0x75, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)]; + crate::word(0x75, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + ]; test_at_alignments(data, &verify); fn verify(pointer_reader: PointerReader) { use crate::private::layout::PrimitiveElement; use crate::traits::FromPointerReader; - let reader = pointer_reader.get_list(crate::private::layout::ElementSize::Bit, None).unwrap(); + let reader = pointer_reader + .get_list(crate::private::layout::ElementSize::Bit, None) + .unwrap(); assert_eq!(reader.len(), 10); assert_eq!(bool::get(&reader, 0), true); @@ -113,7 +121,8 @@ fn bool_list() { assert_eq!(bool::get(&reader, 8), false); assert_eq!(bool::get(&reader, 9), true); - let reader = crate::primitive_list::Reader::::get_from_pointer(&pointer_reader, None).unwrap(); + let reader = + crate::primitive_list::Reader::::get_from_pointer(&pointer_reader, None).unwrap(); assert_eq!(reader.len(), 10); assert_eq!(reader.get(0), true); @@ -144,7 +153,6 @@ fn struct_size() { } } - #[test] fn struct_list_size() { let data: &[crate::Word] = &[ @@ -171,10 +179,8 @@ fn empty_struct_list_size() { let data: &[crate::Word] = &[ // Struct, one pointer crate::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00), - // Inline-composite list, zero words long crate::word(0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00), - // Tag crate::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), ]; diff --git a/capnp/src/private/mod.rs b/capnp/src/private/mod.rs index 252fc19d1..1e6bcdab6 100644 --- a/capnp/src/private/mod.rs +++ b/capnp/src/private/mod.rs @@ -25,16 +25,12 @@ pub mod arena; pub mod capability; -mod primitive; pub mod layout; mod mask; -pub mod units; +mod primitive; mod read_limiter; +pub mod units; mod zero; #[cfg(test)] mod layout_test; - - - - diff --git a/capnp/src/private/primitive.rs b/capnp/src/private/primitive.rs index 3ef93836c..613cad8f4 100644 --- a/capnp/src/private/primitive.rs +++ b/capnp/src/private/primitive.rs @@ -46,7 +46,6 @@ macro_rules! primitive_impl( ); ); - primitive_impl!(u8, 1); primitive_impl!(i8, 1); primitive_impl!(u16, 2); @@ -91,16 +90,26 @@ impl Primitive for f64 { /// A value casted directly from a little-endian byte buffer. On big-endian /// processors, the bytes of the value need to be swapped upon reading and writing. #[repr(C)] -pub struct WireValue where T: Primitive { +pub struct WireValue +where + T: Primitive, +{ value: ::Raw, } -impl WireValue where T: Primitive { +impl WireValue +where + T: Primitive, +{ /// Reads the value, swapping bytes on big-endian processors. #[inline] - pub fn get(&self) -> T { ::get(&self.value) } + pub fn get(&self) -> T { + ::get(&self.value) + } /// Writes the value, swapping bytes on big-endian processors. #[inline] - pub fn set(&mut self, value: T) { ::set(&mut self.value, value) } + pub fn set(&mut self, value: T) { + ::set(&mut self.value, value) + } } diff --git a/capnp/src/private/read_limiter.rs b/capnp/src/private/read_limiter.rs index 413c6a5b3..dff146856 100644 --- a/capnp/src/private/read_limiter.rs +++ b/capnp/src/private/read_limiter.rs @@ -24,8 +24,8 @@ pub use sync::ReadLimiter; #[cfg(feature = "sync_reader")] mod sync { - use alloc::string::String; use crate::{Error, Result}; + use alloc::string::String; use core::sync::atomic::{AtomicUsize, Ordering}; pub struct ReadLimiter { @@ -36,18 +36,14 @@ mod sync { impl ReadLimiter { pub fn new(limit: Option) -> ReadLimiter { match limit { - Some(value) => { - ReadLimiter { - limit: AtomicUsize::new(value), - error_on_limit_exceeded: true, - } - } - None => { - ReadLimiter { - limit: AtomicUsize::new(usize::MAX), - error_on_limit_exceeded: false, - } - } + Some(value) => ReadLimiter { + limit: AtomicUsize::new(value), + error_on_limit_exceeded: true, + }, + None => ReadLimiter { + limit: AtomicUsize::new(usize::MAX), + error_on_limit_exceeded: false, + }, } } @@ -66,7 +62,8 @@ mod sync { // The common case is current >= amount. Note that we only branch once in that case. // If we combined the fields into an Option, we would // need to branch twice in the common case. - self.limit.store(current.wrapping_sub(amount), Ordering::Relaxed); + self.limit + .store(current.wrapping_sub(amount), Ordering::Relaxed); } Ok(()) } @@ -78,8 +75,8 @@ pub use unsync::ReadLimiter; #[cfg(not(feature = "sync_reader"))] mod unsync { - use alloc::string::String; use crate::{Error, Result}; + use alloc::string::String; use core::cell::Cell; pub struct ReadLimiter { @@ -90,18 +87,14 @@ mod unsync { impl ReadLimiter { pub fn new(limit: Option) -> ReadLimiter { match limit { - Some(value) => { - ReadLimiter { - limit: Cell::new(value), - error_on_limit_exceeded: true, - } - } - None => { - ReadLimiter { - limit: Cell::new(usize::MAX), - error_on_limit_exceeded: false, - } - } + Some(value) => ReadLimiter { + limit: Cell::new(value), + error_on_limit_exceeded: true, + }, + None => ReadLimiter { + limit: Cell::new(usize::MAX), + error_on_limit_exceeded: false, + }, } } diff --git a/capnp/src/private/units.rs b/capnp/src/private/units.rs index 3b170139b..90fbf663f 100644 --- a/capnp/src/private/units.rs +++ b/capnp/src/private/units.rs @@ -49,15 +49,15 @@ pub type WirePointerCount16 = u16; pub type WirePointerCount32 = u32; pub type WirePointerCount64 = u64; -pub const BITS_PER_BYTE : BitCount0 = 8; -pub const BITS_PER_WORD : BitCount0 = 64; -pub const BYTES_PER_WORD : ByteCount = 8; +pub const BITS_PER_BYTE: BitCount0 = 8; +pub const BITS_PER_WORD: BitCount0 = 64; +pub const BYTES_PER_WORD: ByteCount = 8; -pub const BITS_PER_POINTER : BitCount0 = 64; -pub const _BYTES_PER_POINTER : ByteCount = 8; -pub const WORDS_PER_POINTER : WordCount = 1; +pub const BITS_PER_POINTER: BitCount0 = 64; +pub const _BYTES_PER_POINTER: ByteCount = 8; +pub const WORDS_PER_POINTER: WordCount = 1; -pub const POINTER_SIZE_IN_WORDS : WordCount = 1; +pub const POINTER_SIZE_IN_WORDS: WordCount = 1; pub fn _bytes_per_element() -> ByteCount { ::core::mem::size_of::() diff --git a/capnp/src/private/zero.rs b/capnp/src/private/zero.rs index a3840807a..2342c2d9d 100644 --- a/capnp/src/private/zero.rs +++ b/capnp/src/private/zero.rs @@ -33,11 +33,11 @@ macro_rules! zero_impl( ) ); -zero_impl!(u8, 0); +zero_impl!(u8, 0); zero_impl!(u16, 0); zero_impl!(u32, 0); zero_impl!(u64, 0); -zero_impl!(i8, 0); +zero_impl!(i8, 0); zero_impl!(i16, 0); zero_impl!(i32, 0); zero_impl!(i64, 0); diff --git a/capnp/src/raw.rs b/capnp/src/raw.rs index 718640826..5883b1207 100644 --- a/capnp/src/raw.rs +++ b/capnp/src/raw.rs @@ -24,36 +24,46 @@ use crate::traits::{IntoInternalListReader, IntoInternalStructReader}; /// Gets a slice view of the data section of a struct. pub fn get_struct_data_section<'a, T>(value: T) -> &'a [u8] - where T: IntoInternalStructReader<'a> +where + T: IntoInternalStructReader<'a>, { - value.into_internal_struct_reader().get_data_section_as_blob() + value + .into_internal_struct_reader() + .get_data_section_as_blob() } /// Gets the pointer section as a list. pub fn get_struct_pointer_section<'a, T>(value: T) -> crate::any_pointer_list::Reader<'a> - where T: IntoInternalStructReader<'a> +where + T: IntoInternalStructReader<'a>, { crate::any_pointer_list::Reader::new( - value.into_internal_struct_reader().get_pointer_section_as_list()) + value + .into_internal_struct_reader() + .get_pointer_section_as_list(), + ) } /// Gets the size of the elements in a list. pub fn get_list_element_size<'a, T>(value: T) -> crate::private::layout::ElementSize - where T: IntoInternalListReader<'a> +where + T: IntoInternalListReader<'a>, { value.into_internal_list_reader().get_element_size() } /// Gets the number of bits between successive elements in a list. pub fn get_list_step_size_in_bits<'a, T>(value: T) -> u32 - where T: IntoInternalListReader<'a> +where + T: IntoInternalListReader<'a>, { value.into_internal_list_reader().get_step_size_in_bits() } /// Gets a slice view of a list, excluding any tag word. pub fn get_list_bytes<'a, T>(value: T) -> &'a [u8] - where T: IntoInternalListReader<'a> +where + T: IntoInternalListReader<'a>, { value.into_internal_list_reader().into_raw_bytes() } diff --git a/capnp/src/serialize.rs b/capnp/src/serialize.rs index 803d34cfb..b1af467fd 100644 --- a/capnp/src/serialize.rs +++ b/capnp/src/serialize.rs @@ -26,17 +26,17 @@ mod no_alloc_slice_segments; pub use no_alloc_slice_segments::NoAllocSliceSegments; +use crate::io::{Read, Write}; use alloc::string::ToString; use alloc::vec::Vec; use core::convert::TryInto; use core::ops::Deref; -use crate::io::{Read, Write}; use crate::message; use crate::private::units::BYTES_PER_WORD; use crate::{Error, Result}; -pub const SEGMENTS_COUNT_LIMIT : usize = 512; +pub const SEGMENTS_COUNT_LIMIT: usize = 512; /// Segments read from a single flat slice of words. pub struct SliceSegments<'a> { @@ -44,10 +44,10 @@ pub struct SliceSegments<'a> { // Each pair represents a segment inside of `words`. // (starting index (in words), ending index (in words)) - segment_indices : Vec<(usize, usize)>, + segment_indices: Vec<(usize, usize)>, } -impl <'a> message::ReaderSegments for SliceSegments<'a> { +impl<'a> message::ReaderSegments for SliceSegments<'a> { fn get_segment(&self, id: u32) -> Option<&[u8]> { if id < self.segment_indices.len() as u32 { let (a, b) = self.segment_indices[id as usize]; @@ -68,9 +68,10 @@ impl <'a> message::ReaderSegments for SliceSegments<'a> { /// /// ALIGNMENT: If the "unaligned" feature is enabled, then there are no alignment requirements on `slice`. /// Otherwise, `slice` must be 8-byte aligned (attempts to read the message will trigger errors). -pub fn read_message_from_flat_slice<'a>(slice: &mut &'a [u8], - options: message::ReaderOptions) - -> Result>> { +pub fn read_message_from_flat_slice<'a>( + slice: &mut &'a [u8], + options: message::ReaderOptions, +) -> Result>> { let all_bytes = *slice; let mut bytes = *slice; let orig_bytes_len = bytes.len(); @@ -82,27 +83,33 @@ pub fn read_message_from_flat_slice<'a>(slice: &mut &'a [u8], assert_eq!(segment_table_bytes_len % BYTES_PER_WORD, 0); let num_words = segment_lengths_builder.total_words(); let body_bytes = &all_bytes[segment_table_bytes_len..]; - if num_words > (body_bytes.len() / BYTES_PER_WORD) { - Err(Error::failed( - format!("Message ends prematurely. Header claimed {} words, but message only has {} words.", - num_words, body_bytes.len() / BYTES_PER_WORD))) + if num_words > (body_bytes.len() / BYTES_PER_WORD) { + Err(Error::failed(format!( + "Message ends prematurely. Header claimed {} words, but message only has {} words.", + num_words, + body_bytes.len() / BYTES_PER_WORD + ))) } else { *slice = &body_bytes[(num_words * BYTES_PER_WORD)..]; - Ok(message::Reader::new(segment_lengths_builder.into_slice_segments(body_bytes), options)) + Ok(message::Reader::new( + segment_lengths_builder.into_slice_segments(body_bytes), + options, + )) } } /// Reads a serialized message (including a segment table) from a flat slice of bytes, without copying. /// The slice is allowed to extend beyond the end of the message. On success, updates `slice` to point /// to the remaining bytes beyond the end of the message. -/// +/// /// Unlike read_message_from_flat_slice_no_alloc it does not do heap allocation (except for error message) /// /// ALIGNMENT: If the "unaligned" feature is enabled, then there are no alignment requirements on `slice`. /// Otherwise, `slice` must be 8-byte aligned (attempts to read the message will trigger errors). -pub fn read_message_from_flat_slice_no_alloc<'a>(slice: &mut &'a [u8], - options: message::ReaderOptions) - -> Result>> { +pub fn read_message_from_flat_slice_no_alloc<'a>( + slice: &mut &'a [u8], + options: message::ReaderOptions, +) -> Result>> { let segments = NoAllocSliceSegments::try_new(slice, options)?; Ok(message::Reader::new(segments, options)) @@ -118,7 +125,7 @@ pub struct BufferSegments { // Each pair represents a segment inside of `words`. // (starting index (in words), ending index (in words)) - segment_indices : Vec<(usize, usize)>, + segment_indices: Vec<(usize, usize)>, } impl> BufferSegments { @@ -131,8 +138,7 @@ impl> BufferSegments { pub fn new(buffer: T, options: message::ReaderOptions) -> Result> { let mut segment_bytes = &*buffer; - let segment_table = match read_segment_table(&mut segment_bytes, options)? - { + let segment_table = match read_segment_table(&mut segment_bytes, options)? { Some(b) => b, None => return Err(Error::failed("empty buffer".to_string())), }; @@ -152,11 +158,14 @@ impl> BufferSegments { } } -impl > message::ReaderSegments for BufferSegments { +impl> message::ReaderSegments for BufferSegments { fn get_segment(&self, id: u32) -> Option<&[u8]> { if id < self.segment_indices.len() as u32 { let (a, b) = self.segment_indices[id as usize]; - Some(&self.buffer[(self.segment_table_bytes_len + a * BYTES_PER_WORD)..(self.segment_table_bytes_len + b * BYTES_PER_WORD)]) + Some( + &self.buffer[(self.segment_table_bytes_len + a * BYTES_PER_WORD) + ..(self.segment_table_bytes_len + b * BYTES_PER_WORD)], + ) } else { None } @@ -167,15 +176,12 @@ impl > message::ReaderSegments for BufferSegments { } } - - - /// Owned memory containing a message's segments sequentialized in a single contiguous buffer. /// The segments are guaranteed to be 8-byte aligned. pub struct OwnedSegments { // Each pair represents a segment inside of `owned_space`. // (starting index (in words), ending index (in words)) - segment_indices : Vec<(usize, usize)>, + segment_indices: Vec<(usize, usize)>, owned_space: Vec, } @@ -228,7 +234,8 @@ impl SegmentLengthsBuilder { /// Pushes a new segment length. The `n`th time (starting at 0) this is called specifies the length of /// the segment with ID `n`. pub fn push_segment(&mut self, length_in_words: usize) { - self.segment_indices.push((self.total_words, self.total_words + length_in_words)); + self.segment_indices + .push((self.total_words, self.total_words + length_in_words)); self.total_words += length_in_words; } @@ -266,25 +273,43 @@ impl SegmentLengthsBuilder { /// Reads a serialized message from a stream with the provided options. /// /// For optimal performance, `read` should be a buffered reader type. -pub fn read_message(mut read: R, options: message::ReaderOptions) -> Result> -where R: Read { +pub fn read_message( + mut read: R, + options: message::ReaderOptions, +) -> Result> +where + R: Read, +{ let owned_segments_builder = match read_segment_table(&mut read, options)? { Some(b) => b, None => return Err(Error::failed("Premature end of file".to_string())), }; - read_segments(&mut read, owned_segments_builder.into_owned_segments(), options) + read_segments( + &mut read, + owned_segments_builder.into_owned_segments(), + options, + ) } /// Like `read_message()`, but returns None instead of an error if there are zero bytes left in /// `read`. This is useful for reading a stream containing an unknown number of messages -- you /// call this function until it returns None. -pub fn try_read_message(mut read: R, options: message::ReaderOptions) -> Result>> -where R: Read { +pub fn try_read_message( + mut read: R, + options: message::ReaderOptions, +) -> Result>> +where + R: Read, +{ let owned_segments_builder = match read_segment_table(&mut read, options)? { Some(b) => b, None => return Ok(None), }; - Ok(Some(read_segments(&mut read, owned_segments_builder.into_owned_segments(), options)?)) + Ok(Some(read_segments( + &mut read, + owned_segments_builder.into_owned_segments(), + options, + )?)) } /// Reads a segment table from `read` and returns the total number of words across all @@ -292,10 +317,12 @@ where R: Read { /// /// The segment table format for streams is defined in the Cap'n Proto /// [encoding spec](https://capnproto.org/encoding.html) -fn read_segment_table(read: &mut R, - options: message::ReaderOptions) - -> Result> - where R: Read +fn read_segment_table( + read: &mut R, + options: message::ReaderOptions, +) -> Result> +where + R: Read, { // read the first Word, which contains segment_count and the 1st segment length let mut buf: [u8; 8] = [0; 8]; @@ -303,7 +330,7 @@ fn read_segment_table(read: &mut R, let n = read.read(&mut buf[..])?; if n == 0 { // Clean EOF on message boundary - return Ok(None) + return Ok(None); } else if n < 8 { read.read_exact(&mut buf[n..])?; } @@ -312,13 +339,20 @@ fn read_segment_table(read: &mut R, let segment_count = u32::from_le_bytes(buf[0..4].try_into().unwrap()).wrapping_add(1) as usize; if segment_count >= SEGMENTS_COUNT_LIMIT { - return Err(Error::failed(format!("Too many segments: {}", segment_count))) + return Err(Error::failed(format!( + "Too many segments: {}", + segment_count + ))); } else if segment_count == 0 { - return Err(Error::failed(format!("Too few segments: {}", segment_count))) + return Err(Error::failed(format!( + "Too few segments: {}", + segment_count + ))); } let mut segment_lengths_builder = SegmentLengthsBuilder::with_capacity(segment_count); - segment_lengths_builder.push_segment(u32::from_le_bytes(buf[4..8].try_into().unwrap()) as usize); + segment_lengths_builder + .push_segment(u32::from_le_bytes(buf[4..8].try_into().unwrap()) as usize); if segment_count > 1 { if segment_count < 4 { read.read_exact(&mut buf)?; @@ -332,7 +366,8 @@ fn read_segment_table(read: &mut R, read.read_exact(&mut segment_sizes[..])?; for idx in 0..(segment_count - 1) { let segment_len = - u32::from_le_bytes(segment_sizes[(idx * 4)..(idx + 1) * 4].try_into().unwrap()) as usize; + u32::from_le_bytes(segment_sizes[(idx * 4)..(idx + 1) * 4].try_into().unwrap()) + as usize; segment_lengths_builder.push_segment(segment_len); } } @@ -343,9 +378,11 @@ fn read_segment_table(read: &mut R, // size to make the receiver allocate excessive space and possibly crash. if let Some(limit) = options.traversal_limit_in_words { if segment_lengths_builder.total_words() > limit { - return Err(Error::failed( - format!("Message has {} words, which is too large. To increase the limit on the \ - receiving end, see capnp::message::ReaderOptions.", segment_lengths_builder.total_words()))) + return Err(Error::failed(format!( + "Message has {} words, which is too large. To increase the limit on the \ + receiving end, see capnp::message::ReaderOptions.", + segment_lengths_builder.total_words() + ))); } } @@ -353,18 +390,22 @@ fn read_segment_table(read: &mut R, } /// Reads segments from `read`. -fn read_segments(read: &mut R, - mut owned_segments: OwnedSegments, - options: message::ReaderOptions) - -> Result> -where R: Read { +fn read_segments( + read: &mut R, + mut owned_segments: OwnedSegments, + options: message::ReaderOptions, +) -> Result> +where + R: Read, +{ read.read_exact(&mut owned_segments[..])?; Ok(crate::message::Reader::new(owned_segments, options)) } /// Constructs a flat vector containing the entire message, including a segment header. pub fn write_message_to_words(message: &message::Builder) -> Vec - where A: message::Allocator +where + A: message::Allocator, { flatten_segments(&*message.get_segments_for_output()) } @@ -372,7 +413,8 @@ pub fn write_message_to_words(message: &message::Builder) -> Vec /// Like `write_message_to_words()`, but takes a `ReaderSegments`, allowing it to be /// used on `message::Reader` objects (via `into_segments()`). pub fn write_message_segments_to_words(message: &R) -> Vec - where R: message::ReaderSegments +where + R: message::ReaderSegments, { flatten_segments(message) } @@ -399,7 +441,10 @@ fn flatten_segments(segments: &R) -> Vec(mut write: W, message: &message::Builder) -> Result<()> - where W: Write, A: message::Allocator { +where + W: Write, + A: message::Allocator, +{ let segments = message.get_segments_for_output(); write_segment_table(&mut write, &segments)?; write_segments(&mut write, &segments) @@ -408,13 +453,18 @@ pub fn write_message(mut write: W, message: &message::Builder) -> Resul /// Like `write_message()`, but takes a `ReaderSegments`, allowing it to be /// used on `message::Reader` objects (via `into_segments()`). pub fn write_message_segments(mut write: W, segments: &R) -> Result<()> - where W: Write, R: message::ReaderSegments { +where + W: Write, + R: message::ReaderSegments, +{ write_segment_table_internal(&mut write, segments)?; write_segments(&mut write, segments) } fn write_segment_table(write: &mut W, segments: &[&[u8]]) -> Result<()> -where W: Write { +where + W: Write, +{ write_segment_table_internal(write, segments) } @@ -422,34 +472,47 @@ where W: Write { /// /// `segments` must contain at least one segment. fn write_segment_table_internal(write: &mut W, segments: &R) -> Result<()> -where W: Write, R: message::ReaderSegments + ?Sized { +where + W: Write, + R: message::ReaderSegments + ?Sized, +{ let mut buf: [u8; 8] = [0; 8]; let segment_count = segments.len(); // write the first Word, which contains segment_count and the 1st segment length buf[0..4].copy_from_slice(&(segment_count as u32 - 1).to_le_bytes()); - buf[4..8].copy_from_slice(&((segments.get_segment(0).unwrap().len() / BYTES_PER_WORD)as u32).to_le_bytes()); + buf[4..8].copy_from_slice( + &((segments.get_segment(0).unwrap().len() / BYTES_PER_WORD) as u32).to_le_bytes(), + ); write.write_all(&buf)?; if segment_count > 1 { if segment_count < 4 { for idx in 1..segment_count { buf[(idx - 1) * 4..idx * 4].copy_from_slice( - &((segments.get_segment(idx as u32).unwrap().len() / BYTES_PER_WORD) as u32).to_le_bytes()); + &((segments.get_segment(idx as u32).unwrap().len() / BYTES_PER_WORD) as u32) + .to_le_bytes(), + ); } if segment_count == 2 { - for b in &mut buf[4..8] { *b = 0 } + for b in &mut buf[4..8] { + *b = 0 + } } write.write_all(&buf)?; } else { let mut buf = vec![0; (segment_count & !1) * 4]; for idx in 1..segment_count { buf[(idx - 1) * 4..idx * 4].copy_from_slice( - &((segments.get_segment(idx as u32).unwrap().len() / BYTES_PER_WORD) as u32).to_le_bytes()); + &((segments.get_segment(idx as u32).unwrap().len() / BYTES_PER_WORD) as u32) + .to_le_bytes(), + ); } if segment_count % 2 == 0 { let start_idx = buf.len() - 4; - for b in &mut buf[start_idx ..] { *b = 0 } + for b in &mut buf[start_idx..] { + *b = 0 + } } write.write_all(&buf)?; } @@ -459,7 +522,9 @@ where W: Write, R: message::ReaderSegments + ?Sized { /// Writes segments to `write`. fn write_segments(write: &mut W, segments: &R) -> Result<()> -where W: Write { +where + W: Write, +{ for i in 0.. { if let Some(segment) = segments.get_segment(i) { write.write_all(segment)?; @@ -487,7 +552,8 @@ fn compute_serialized_size(segments: &R) -> /// Multiply this by 8 (or `std::mem::size_of::()`) to get the number of bytes /// that [`write_message()`](fn.write_message.html) will write. pub fn compute_serialized_size_in_words(message: &crate::message::Builder) -> usize - where A: crate::message::Allocator +where + A: crate::message::Allocator, { compute_serialized_size(&message.get_segments_for_output()) } @@ -496,20 +562,26 @@ pub fn compute_serialized_size_in_words(message: &crate::message::Builder) pub mod test { use alloc::vec::Vec; - use crate::io::{Write, Read}; + use crate::io::{Read, Write}; use quickcheck::{quickcheck, TestResult}; + use super::{ + flatten_segments, read_message, read_message_from_flat_slice, read_segment_table, + try_read_message, write_segment_table, write_segments, + }; use crate::message; use crate::message::ReaderSegments; - use super::{read_message, try_read_message, read_message_from_flat_slice, flatten_segments, - read_segment_table, write_segment_table, write_segments}; /// Writes segments as if they were a Capnproto message. - pub fn write_message_segments(write: &mut W, segments: &[Vec]) where W: Write { - let borrowed_segments: &[&[u8]] = &segments.iter() - .map(|segment| crate::Word::words_to_bytes(&segment[..])) - .collect::>()[..]; + pub fn write_message_segments(write: &mut W, segments: &[Vec]) + where + W: Write, + { + let borrowed_segments: &[&[u8]] = &segments + .iter() + .map(|segment| crate::Word::words_to_bytes(&segment[..])) + .collect::>()[..]; write_segment_table(write, borrowed_segments).unwrap(); write_segments(write, borrowed_segments).unwrap(); } @@ -517,73 +589,125 @@ pub mod test { #[test] fn try_read_empty() { let mut buf: &[u8] = &[]; - assert!(try_read_message(&mut buf, message::ReaderOptions::new()).unwrap().is_none()); + assert!(try_read_message(&mut buf, message::ReaderOptions::new()) + .unwrap() + .is_none()); } #[test] fn test_read_segment_table() { let mut buf = vec![]; - buf.extend([0,0,0,0, // 1 segments - 0,0,0,0] // 0 length - .iter().cloned()); - let segment_lengths_builder = read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).unwrap().unwrap(); + buf.extend( + [ + 0, 0, 0, 0, // 1 segments + 0, 0, 0, 0, + ] // 0 length + .iter() + .cloned(), + ); + let segment_lengths_builder = + read_segment_table(&mut &buf[..], message::ReaderOptions::new()) + .unwrap() + .unwrap(); assert_eq!(0, segment_lengths_builder.total_words()); - assert_eq!(vec![(0,0)], segment_lengths_builder.to_segment_indices()); + assert_eq!(vec![(0, 0)], segment_lengths_builder.to_segment_indices()); buf.clear(); - buf.extend([0,0,0,0, // 1 segments - 1,0,0,0] // 1 length - .iter().cloned()); - let segment_lengths_builder = read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).unwrap().unwrap(); + buf.extend( + [ + 0, 0, 0, 0, // 1 segments + 1, 0, 0, 0, + ] // 1 length + .iter() + .cloned(), + ); + let segment_lengths_builder = + read_segment_table(&mut &buf[..], message::ReaderOptions::new()) + .unwrap() + .unwrap(); assert_eq!(1, segment_lengths_builder.total_words()); - assert_eq!(vec![(0,1)], segment_lengths_builder.to_segment_indices()); + assert_eq!(vec![(0, 1)], segment_lengths_builder.to_segment_indices()); buf.clear(); - buf.extend([1,0,0,0, // 2 segments - 1,0,0,0, // 1 length - 1,0,0,0, // 1 length - 0,0,0,0] // padding - .iter().cloned()); - let segment_lengths_builder = read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).unwrap().unwrap(); + buf.extend( + [ + 1, 0, 0, 0, // 2 segments + 1, 0, 0, 0, // 1 length + 1, 0, 0, 0, // 1 length + 0, 0, 0, 0, + ] // padding + .iter() + .cloned(), + ); + let segment_lengths_builder = + read_segment_table(&mut &buf[..], message::ReaderOptions::new()) + .unwrap() + .unwrap(); assert_eq!(2, segment_lengths_builder.total_words()); - assert_eq!(vec![(0,1), (1, 2)], segment_lengths_builder.to_segment_indices()); + assert_eq!( + vec![(0, 1), (1, 2)], + segment_lengths_builder.to_segment_indices() + ); buf.clear(); - buf.extend([2,0,0,0, // 3 segments - 1,0,0,0, // 1 length - 1,0,0,0, // 1 length - 0,1,0,0] // 256 length - .iter().cloned()); - let segment_lengths_builder = read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).unwrap().unwrap(); + buf.extend( + [ + 2, 0, 0, 0, // 3 segments + 1, 0, 0, 0, // 1 length + 1, 0, 0, 0, // 1 length + 0, 1, 0, 0, + ] // 256 length + .iter() + .cloned(), + ); + let segment_lengths_builder = + read_segment_table(&mut &buf[..], message::ReaderOptions::new()) + .unwrap() + .unwrap(); assert_eq!(258, segment_lengths_builder.total_words()); - assert_eq!(vec![(0,1), (1, 2), (2, 258)], segment_lengths_builder.to_segment_indices()); + assert_eq!( + vec![(0, 1), (1, 2), (2, 258)], + segment_lengths_builder.to_segment_indices() + ); buf.clear(); - buf.extend([3,0,0,0, // 4 segments - 77,0,0,0, // 77 length - 23,0,0,0, // 23 length - 1,0,0,0, // 1 length - 99,0,0,0, // 99 length - 0,0,0,0] // padding - .iter().cloned()); - let segment_lengths_builder = read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).unwrap().unwrap(); + buf.extend( + [ + 3, 0, 0, 0, // 4 segments + 77, 0, 0, 0, // 77 length + 23, 0, 0, 0, // 23 length + 1, 0, 0, 0, // 1 length + 99, 0, 0, 0, // 99 length + 0, 0, 0, 0, + ] // padding + .iter() + .cloned(), + ); + let segment_lengths_builder = + read_segment_table(&mut &buf[..], message::ReaderOptions::new()) + .unwrap() + .unwrap(); assert_eq!(200, segment_lengths_builder.total_words()); - assert_eq!(vec![(0,77), (77, 100), (100, 101), (101, 200)], segment_lengths_builder.to_segment_indices()); + assert_eq!( + vec![(0, 77), (77, 100), (100, 101), (101, 200)], + segment_lengths_builder.to_segment_indices() + ); buf.clear(); } - struct MaxRead where R: Read { + struct MaxRead + where + R: Read, + { inner: R, max: usize, } - impl Read for MaxRead where R: Read { + impl Read for MaxRead + where + R: Read, + { fn read(&mut self, buf: &mut [u8]) -> crate::Result { if buf.len() <= self.max { self.inner.read(buf) @@ -597,97 +721,140 @@ pub mod test { fn test_read_segment_table_max_read() { // Make sure things still work well when we read less than a word at a time. let mut buf: Vec = vec![]; - buf.extend([0,0,0,0, // 1 segments - 1,0,0,0] // 1 length - .iter().cloned()); - let segment_lengths_builder = read_segment_table(&mut MaxRead { inner: &buf[..], max: 2}, - message::ReaderOptions::new()).unwrap().unwrap(); + buf.extend( + [ + 0, 0, 0, 0, // 1 segments + 1, 0, 0, 0, + ] // 1 length + .iter() + .cloned(), + ); + let segment_lengths_builder = read_segment_table( + &mut MaxRead { + inner: &buf[..], + max: 2, + }, + message::ReaderOptions::new(), + ) + .unwrap() + .unwrap(); assert_eq!(1, segment_lengths_builder.total_words()); - assert_eq!(vec![(0,1)], segment_lengths_builder.to_segment_indices()); + assert_eq!(vec![(0, 1)], segment_lengths_builder.to_segment_indices()); } #[test] fn test_read_invalid_segment_table() { let mut buf = vec![]; - buf.extend([0,2,0,0].iter().cloned()); // 513 segments + buf.extend([0, 2, 0, 0].iter().cloned()); // 513 segments buf.extend([0; 513 * 4].iter().cloned()); - assert!(read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).is_err()); + assert!(read_segment_table(&mut &buf[..], message::ReaderOptions::new()).is_err()); buf.clear(); - buf.extend([0,0,0,0].iter().cloned()); // 1 segments - assert!(read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).is_err()); + buf.extend([0, 0, 0, 0].iter().cloned()); // 1 segments + assert!(read_segment_table(&mut &buf[..], message::ReaderOptions::new()).is_err()); buf.clear(); - buf.extend([0,0,0,0].iter().cloned()); // 1 segments + buf.extend([0, 0, 0, 0].iter().cloned()); // 1 segments buf.extend([0; 3].iter().cloned()); - assert!(read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).is_err()); + assert!(read_segment_table(&mut &buf[..], message::ReaderOptions::new()).is_err()); buf.clear(); - buf.extend([255,255,255,255].iter().cloned()); // 0 segments - assert!(read_segment_table(&mut &buf[..], - message::ReaderOptions::new()).is_err()); + buf.extend([255, 255, 255, 255].iter().cloned()); // 0 segments + assert!(read_segment_table(&mut &buf[..], message::ReaderOptions::new()).is_err()); buf.clear(); } #[test] fn test_write_segment_table() { - let mut buf = vec![]; let segment_0 = [0u8; 0]; - let segment_1 = [1u8,1,1,1,1,1,1,1]; + let segment_1 = [1u8, 1, 1, 1, 1, 1, 1, 1]; let segment_199 = [201u8; 199 * 8]; write_segment_table(&mut buf, &[&segment_0]).unwrap(); - assert_eq!(&[0,0,0,0, // 1 segments - 0,0,0,0], // 0 length - &buf[..]); + assert_eq!( + &[ + 0, 0, 0, 0, // 1 segments + 0, 0, 0, 0 + ], // 0 length + &buf[..] + ); buf.clear(); write_segment_table(&mut buf, &[&segment_1]).unwrap(); - assert_eq!(&[0,0,0,0, // 1 segments - 1,0,0,0], // 1 length - &buf[..]); + assert_eq!( + &[ + 0, 0, 0, 0, // 1 segments + 1, 0, 0, 0 + ], // 1 length + &buf[..] + ); buf.clear(); write_segment_table(&mut buf, &[&segment_199]).unwrap(); - assert_eq!(&[0,0,0,0, // 1 segments - 199,0,0,0], // 199 length - &buf[..]); + assert_eq!( + &[ + 0, 0, 0, 0, // 1 segments + 199, 0, 0, 0 + ], // 199 length + &buf[..] + ); buf.clear(); write_segment_table(&mut buf, &[&segment_0, &segment_1]).unwrap(); - assert_eq!(&[1,0,0,0, // 2 segments - 0,0,0,0, // 0 length - 1,0,0,0, // 1 length - 0,0,0,0], // padding - &buf[..]); + assert_eq!( + &[ + 1, 0, 0, 0, // 2 segments + 0, 0, 0, 0, // 0 length + 1, 0, 0, 0, // 1 length + 0, 0, 0, 0 + ], // padding + &buf[..] + ); buf.clear(); - write_segment_table(&mut buf, - &[&segment_199, &segment_1, &segment_199, &segment_0]).unwrap(); - assert_eq!(&[3,0,0,0, // 4 segments - 199,0,0,0, // 199 length - 1,0,0,0, // 1 length - 199,0,0,0, // 199 length - 0,0,0,0, // 0 length - 0,0,0,0], // padding - &buf[..]); + write_segment_table( + &mut buf, + &[&segment_199, &segment_1, &segment_199, &segment_0], + ) + .unwrap(); + assert_eq!( + &[ + 3, 0, 0, 0, // 4 segments + 199, 0, 0, 0, // 199 length + 1, 0, 0, 0, // 1 length + 199, 0, 0, 0, // 199 length + 0, 0, 0, 0, // 0 length + 0, 0, 0, 0 + ], // padding + &buf[..] + ); buf.clear(); - write_segment_table(&mut buf, - &[&segment_199, &segment_1, &segment_199, &segment_0, &segment_1]).unwrap(); - assert_eq!(&[4,0,0,0, // 5 segments - 199,0,0,0, // 199 length - 1,0,0,0, // 1 length - 199,0,0,0, // 199 length - 0,0,0,0, // 0 length - 1,0,0,0], // 1 length - &buf[..]); + write_segment_table( + &mut buf, + &[ + &segment_199, + &segment_1, + &segment_199, + &segment_0, + &segment_1, + ], + ) + .unwrap(); + assert_eq!( + &[ + 4, 0, 0, 0, // 5 segments + 199, 0, 0, 0, // 199 length + 1, 0, 0, 0, // 1 length + 199, 0, 0, 0, // 199 length + 0, 0, 0, 0, // 0 length + 1, 0, 0, 0 + ], // 1 length + &buf[..] + ); buf.clear(); } @@ -725,42 +892,55 @@ pub mod test { #[test] fn read_message_from_flat_slice_with_remainder() { - let segments = vec![vec![123,0,0,0,0,0,0,0], - vec![4,0,0,0,0,0,0,0, - 5,0,0,0,0,0,0,0]]; + let segments = vec![ + vec![123, 0, 0, 0, 0, 0, 0, 0], + vec![4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0], + ]; - let borrowed_segments: &[&[u8]] = &segments.iter() + let borrowed_segments: &[&[u8]] = &segments + .iter() .map(|segment| &segment[..]) .collect::>()[..]; let mut bytes = flatten_segments(borrowed_segments); - let extra_bytes: &[u8] = &[9,9,9,9,9,9,9,9,8,7,6,5,4,3,2,1]; - for &b in extra_bytes { bytes.push(b); } + let extra_bytes: &[u8] = &[9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1]; + for &b in extra_bytes { + bytes.push(b); + } let mut byte_slice = &bytes[..]; - let message = read_message_from_flat_slice(&mut byte_slice, message::ReaderOptions::new()).unwrap(); + let message = + read_message_from_flat_slice(&mut byte_slice, message::ReaderOptions::new()).unwrap(); assert_eq!(byte_slice, extra_bytes); let result_segments = message.into_segments(); for (idx, segment) in segments.iter().enumerate() { assert_eq!( *segment, - result_segments.get_segment(idx as u32).expect("segment should exist")); + result_segments + .get_segment(idx as u32) + .expect("segment should exist") + ); } } #[test] fn read_message_from_flat_slice_too_short() { - let segments = vec![vec![1,0,0,0,0,0,0,0], - vec![2,0,0,0,0,0,0,0, - 3,0,0,0,0,0,0,0]]; + let segments = vec![ + vec![1, 0, 0, 0, 0, 0, 0, 0], + vec![2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0], + ]; - let borrowed_segments: &[&[u8]] = &segments.iter() + let borrowed_segments: &[&[u8]] = &segments + .iter() .map(|segment| &segment[..]) .collect::>()[..]; let mut bytes = flatten_segments(borrowed_segments); while !bytes.is_empty() { bytes.pop(); - assert!(read_message_from_flat_slice(&mut &bytes[..], message::ReaderOptions::new()).is_err()); + assert!( + read_message_from_flat_slice(&mut &bytes[..], message::ReaderOptions::new()) + .is_err() + ); } } @@ -770,11 +950,15 @@ pub mod test { let mut m = message::Builder::new_default(); { let root: crate::any_pointer::Builder = m.init_root(); - let _list_builder: crate::primitive_list::Builder = root.initn_as(LIST_LENGTH_IN_WORDS); + let _list_builder: crate::primitive_list::Builder = + root.initn_as(LIST_LENGTH_IN_WORDS); } // The message body has a list pointer (one word) and the list (LIST_LENGTH_IN_WORDS words). // The message has one segment, so the header is one word. - assert_eq!(super::compute_serialized_size_in_words(&m) as u32, 1 + 1 + LIST_LENGTH_IN_WORDS) + assert_eq!( + super::compute_serialized_size_in_words(&m) as u32, + 1 + 1 + LIST_LENGTH_IN_WORDS + ) } } diff --git a/capnp/src/serialize/no_alloc_slice_segments.rs b/capnp/src/serialize/no_alloc_slice_segments.rs index a02840835..b6a48424e 100644 --- a/capnp/src/serialize/no_alloc_slice_segments.rs +++ b/capnp/src/serialize/no_alloc_slice_segments.rs @@ -322,8 +322,7 @@ mod tests { use crate::{ message::{ReaderOptions, ReaderSegments}, serialize::{self, no_alloc_slice_segments::calculate_data_offset}, - OutputSegments, - Word, + OutputSegments, Word, }; use super::{ diff --git a/capnp/src/serialize_packed.rs b/capnp/src/serialize_packed.rs index 846712e55..9f2ebf77a 100644 --- a/capnp/src/serialize_packed.rs +++ b/capnp/src/serialize_packed.rs @@ -22,24 +22,30 @@ //! Reading and writing of messages using the //! [packed stream encoding](https://capnproto.org/encoding.html#packing). +use crate::io::{BufRead, Read, Write}; use alloc::string::ToString; use core::{mem, ptr, slice}; -use crate::io::{Read, BufRead, Write}; +use crate::message; use crate::serialize; use crate::Result; -use crate::message; /// A `BufRead` wrapper that unpacks packed data. Returns an error on any `read()` /// call that would end within an all-zero (tag 0x00) or uncompressed (tag 0xff) /// run of words. Calls that come from `serialize_packed::read_message()` and /// `serialize_packed::try_read_message()` always mirror `write()` calls from /// `serialize_packed::write_message()`, so they always safely span such runs. -struct PackedRead where R: BufRead { +struct PackedRead +where + R: BufRead, +{ inner: R, } -impl PackedRead where R: BufRead { +impl PackedRead +where + R: BufRead, +{ fn get_read_buffer(&mut self) -> Result<(*const u8, *const u8)> { let buf = self.inner.fill_buf()?; Ok((buf.as_ptr(), buf.as_ptr().wrapping_add(buf.len()))) @@ -68,10 +74,15 @@ macro_rules! refresh_buffer( ); ); -impl Read for PackedRead where R: BufRead { +impl Read for PackedRead +where + R: BufRead, +{ fn read(&mut self, out_buf: &mut [u8]) -> Result { let len = out_buf.len(); - if len == 0 { return Ok(0); } + if len == 0 { + return Ok(0); + } assert!(len % 8 == 0, "PackedRead reads must be word-aligned."); @@ -89,8 +100,11 @@ impl Read for PackedRead where R: BufRead { loop { let tag: u8; - assert_eq!(ptr_sub(out, out_buf.as_mut_ptr()) % 8, 0, - "Output pointer should always be aligned here."); + assert_eq!( + ptr_sub(out, out_buf.as_mut_ptr()) % 8, + 0, + "Output pointer should always be aligned here." + ); if ptr_sub(in_end, in_ptr) < 10 { if ptr_sub(in_end, in_ptr) == 0 { @@ -107,8 +121,15 @@ impl Read for PackedRead where R: BufRead { for i in 0..8 { if (tag & (1u8 << i)) != 0 { if ptr_sub(in_end, in_ptr) == 0 { - refresh_buffer!(self, size, in_ptr, in_end, - out, out_buf, buffer_begin); + refresh_buffer!( + self, + size, + in_ptr, + in_end, + out, + out_buf, + buffer_begin + ); } *out = *in_ptr; out = out.offset(1); @@ -120,8 +141,7 @@ impl Read for PackedRead where R: BufRead { } if ptr_sub(in_end, in_ptr) == 0 && (tag == 0 || tag == 0xff) { - refresh_buffer!(self, size, in_ptr, in_end, - out, out_buf, buffer_begin); + refresh_buffer!(self, size, in_ptr, in_end, out, out_buf, buffer_begin); } } else { tag = *in_ptr; @@ -135,28 +155,35 @@ impl Read for PackedRead where R: BufRead { } } if tag == 0 { - assert!(ptr_sub(in_end, in_ptr) > 0, - "Should always have non-empty buffer here."); + assert!( + ptr_sub(in_end, in_ptr) > 0, + "Should always have non-empty buffer here." + ); - let run_length : usize = (*in_ptr) as usize * 8; + let run_length: usize = (*in_ptr) as usize * 8; in_ptr = in_ptr.offset(1); if run_length > ptr_sub(out_end, out) { - return Err(crate::Error::failed("Packed input did not end cleanly on a segment boundary.".to_string())); + return Err(crate::Error::failed( + "Packed input did not end cleanly on a segment boundary.".to_string(), + )); } ptr::write_bytes(out, 0, run_length); out = out.add(run_length); - } else if tag == 0xff { - assert!(ptr_sub(in_end, in_ptr) > 0, - "Should always have non-empty buffer here"); + assert!( + ptr_sub(in_end, in_ptr) > 0, + "Should always have non-empty buffer here" + ); - let mut run_length : usize = (*in_ptr) as usize * 8; + let mut run_length: usize = (*in_ptr) as usize * 8; in_ptr = in_ptr.offset(1); if run_length > ptr_sub(out_end, out) { - return Err(crate::Error::failed("Packed input did not end cleanly on a segment boundary.".to_string())); + return Err(crate::Error::failed( + "Packed input did not end cleanly on a segment boundary.".to_string(), + )); } let in_remaining = ptr_sub(in_end, in_ptr); @@ -202,30 +229,40 @@ impl Read for PackedRead where R: BufRead { } /// Reads a packed message from a stream using the provided options. -pub fn read_message(read: R, - options: message::ReaderOptions) - -> Result> - where R: BufRead +pub fn read_message( + read: R, + options: message::ReaderOptions, +) -> Result> +where + R: BufRead, { let packed_read = PackedRead { inner: read }; serialize::read_message(packed_read, options) } /// Like read_message(), but returns None instead of an error if there are zero bytes left in `read`. -pub fn try_read_message(read: R, - options: message::ReaderOptions) - -> Result>> - where R: BufRead +pub fn try_read_message( + read: R, + options: message::ReaderOptions, +) -> Result>> +where + R: BufRead, { let packed_read = PackedRead { inner: read }; serialize::try_read_message(packed_read, options) } -struct PackedWrite where W: Write { +struct PackedWrite +where + W: Write, +{ inner: W, } -impl Write for PackedWrite where W: Write { +impl Write for PackedWrite +where + W: Write, +{ fn write_all(&mut self, in_buf: &[u8]) -> Result<()> { unsafe { let mut buf_idx: usize = 0; @@ -235,7 +272,6 @@ impl Write for PackedWrite where W: Write { let in_end: *const u8 = in_buf.as_ptr().wrapping_add(in_buf.len()); while in_ptr < in_end { - if buf_idx + 10 > buf.len() { //# Oops, we're out of space. We need at least 10 //# bytes for the fast path, since we don't @@ -287,9 +323,14 @@ impl Write for PackedWrite where W: Write { buf_idx += bit7 as usize; in_ptr = in_ptr.offset(1); - let tag: u8 = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3) - | (bit4 << 4) | (bit5 << 5) | (bit6 << 6) | (bit7 << 7); - + let tag: u8 = bit0 + | (bit1 << 1) + | (bit2 << 2) + | (bit3 << 3) + | (bit4 << 4) + | (bit5 << 5) + | (bit6 << 6) + | (bit7 << 7); *buf.get_unchecked_mut(tag_pos) = tag; @@ -298,16 +339,17 @@ impl Write for PackedWrite where W: Write { //# consecutive zero words (not including the first //# one). - let mut in_word : *const [u8; 8] = in_ptr as *const [u8; 8]; - let mut limit : *const [u8; 8] = in_end as *const [u8; 8]; + let mut in_word: *const [u8; 8] = in_ptr as *const [u8; 8]; + let mut limit: *const [u8; 8] = in_end as *const [u8; 8]; if ptr_sub(limit, in_word) > 255 { limit = in_word.offset(255); } - while in_word < limit && *in_word == [0;8] { + while in_word < limit && *in_word == [0; 8] { in_word = in_word.offset(1); } - *buf.get_unchecked_mut(buf_idx) = ptr_sub(in_word, in_ptr as *const [u8; 8]) as u8; + *buf.get_unchecked_mut(buf_idx) = + ptr_sub(in_word, in_ptr as *const [u8; 8]) as u8; buf_idx += 1; in_ptr = in_word as *const u8; } else if tag == 0xff { @@ -347,7 +389,8 @@ impl Write for PackedWrite where W: Write { self.inner.write_all(&buf[..buf_idx])?; buf_idx = 0; - self.inner.write_all(slice::from_raw_parts::(run_start, count))?; + self.inner + .write_all(slice::from_raw_parts::(run_start, count))?; } } @@ -359,7 +402,9 @@ impl Write for PackedWrite where W: Write { /// Writes a packed message to a stream. pub fn write_message(write: W, message: &crate::message::Builder) -> Result<()> - where W: Write, A: crate::message::Allocator +where + W: Write, + A: crate::message::Allocator, { let packed_write = PackedWrite { inner: write }; serialize::write_message(packed_write, message) @@ -370,14 +415,14 @@ mod tests { use alloc::string::ToString; use alloc::vec::Vec; - use crate::io::{Write, Read}; + use crate::io::{Read, Write}; use quickcheck::{quickcheck, TestResult}; - use crate::message::{ReaderOptions}; + use super::read_message; + use crate::message::ReaderOptions; use crate::serialize::test::write_message_segments; use crate::serialize_packed::{PackedRead, PackedWrite}; - use super::read_message; #[test] pub fn premature_eof() { @@ -404,7 +449,9 @@ mod tests { let mut bytes: Vec = vec![0; packed.len()]; { - let mut packed_write = PackedWrite { inner: &mut bytes[..] }; + let mut packed_write = PackedWrite { + inner: &mut bytes[..], + }; packed_write.write_all(unpacked).unwrap(); } @@ -418,28 +465,61 @@ mod tests { #[test] pub fn simple_packing() { check_packing(&[], &[]); - check_packing(&[0; 8], &[0,0]); - check_packing(&[0,0,12,0,0,34,0,0], &[0x24,12,34]); - check_packing(&[1,3,2,4,5,7,6,8], &[0xff,1,3,2,4,5,7,6,8,0]); - check_packing(&[0,0,0,0,0,0,0,0,1,3,2,4,5,7,6,8], &[0,0,0xff,1,3,2,4,5,7,6,8,0]); - check_packing(&[0,0,12,0,0,34,0,0,1,3,2,4,5,7,6,8], &[0x24,12,34,0xff,1,3,2,4,5,7,6,8,0]); - check_packing(&[1,3,2,4,5,7,6,8,8,6,7,4,5,2,3,1], &[0xff,1,3,2,4,5,7,6,8,1,8,6,7,4,5,2,3,1]); + check_packing(&[0; 8], &[0, 0]); + check_packing(&[0, 0, 12, 0, 0, 34, 0, 0], &[0x24, 12, 34]); + check_packing( + &[1, 3, 2, 4, 5, 7, 6, 8], + &[0xff, 1, 3, 2, 4, 5, 7, 6, 8, 0], + ); + check_packing( + &[0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 4, 5, 7, 6, 8], + &[0, 0, 0xff, 1, 3, 2, 4, 5, 7, 6, 8, 0], + ); + check_packing( + &[0, 0, 12, 0, 0, 34, 0, 0, 1, 3, 2, 4, 5, 7, 6, 8], + &[0x24, 12, 34, 0xff, 1, 3, 2, 4, 5, 7, 6, 8, 0], + ); + check_packing( + &[1, 3, 2, 4, 5, 7, 6, 8, 8, 6, 7, 4, 5, 2, 3, 1], + &[0xff, 1, 3, 2, 4, 5, 7, 6, 8, 1, 8, 6, 7, 4, 5, 2, 3, 1], + ); check_packing( - &[1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 0,2,4,0,9,0,5,1], - &[0xff,1,2,3,4,5,6,7,8, 3, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, - 0xd6,2,4,9,5,1]); + &[ + 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, + 5, 6, 7, 8, 0, 2, 4, 0, 9, 0, 5, 1, + ], + &[ + 0xff, 1, 2, 3, 4, 5, 6, 7, 8, 3, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, + 2, 3, 4, 5, 6, 7, 8, 0xd6, 2, 4, 9, 5, 1, + ], + ); check_packing( - &[1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 6,2,4,3,9,0,5,1, 1,2,3,4,5,6,7,8, 0,2,4,0,9,0,5,1], - &[0xff,1,2,3,4,5,6,7,8, 3, 1,2,3,4,5,6,7,8, 6,2,4,3,9,0,5,1, 1,2,3,4,5,6,7,8, - 0xd6,2,4,9,5,1]); + &[ + 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 6, 2, 4, 3, 9, 0, 5, 1, 1, 2, 3, 4, + 5, 6, 7, 8, 0, 2, 4, 0, 9, 0, 5, 1, + ], + &[ + 0xff, 1, 2, 3, 4, 5, 6, 7, 8, 3, 1, 2, 3, 4, 5, 6, 7, 8, 6, 2, 4, 3, 9, 0, 5, 1, 1, + 2, 3, 4, 5, 6, 7, 8, 0xd6, 2, 4, 9, 5, 1, + ], + ); check_packing( - &[8,0,100,6,0,1,1,2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,0,2,0,3,1], - &[0xed,8,100,6,1,1,2, 0,2, 0xd4,1,2,3,1]); + &[ + 8, 0, 100, 6, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 1, + ], + &[0xed, 8, 100, 6, 1, 1, 2, 0, 2, 0xd4, 1, 2, 3, 1], + ); - check_packing(&[0; 16], &[0,1]); - check_packing(&[0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0], &[0,2]); + check_packing(&[0; 16], &[0, 1]); + check_packing( + &[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + &[0, 2], + ); } #[cfg_attr(miri, ignore)] // miri takes a long time with quickcheck @@ -472,14 +552,16 @@ mod tests { #[test] fn did_not_end_cleanly_on_a_segment_boundary() { let packed = &[0xff, 1, 2, 3, 4, 5, 6, 7, 8, 37, 1, 2]; - let mut packed_read = PackedRead {inner: &packed[..]}; + let mut packed_read = PackedRead { inner: &packed[..] }; let mut bytes: Vec = vec![0; 200]; match packed_read.read_exact(&mut bytes[..]) { Ok(_) => panic!("should have been an error"), Err(e) => { - assert_eq!(e.to_string(), - "Failed: Packed input did not end cleanly on a segment boundary."); + assert_eq!( + e.to_string(), + "Failed: Packed input did not end cleanly on a segment boundary." + ); } } } @@ -487,7 +569,7 @@ mod tests { #[test] fn premature_end_of_packed_input() { fn helper(packed: &[u8]) { - let mut packed_read = PackedRead {inner: packed}; + let mut packed_read = PackedRead { inner: packed }; let mut bytes: Vec = vec![0; 200]; match packed_read.read_exact(&mut bytes[..]) { @@ -513,10 +595,11 @@ mod tests { check_unpacks_to( packed_buf, - &[4, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0]); + &[ + 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + ); // At one point, this failed due to serialize::read_message() // reading the segment table only one word at a time. diff --git a/capnp/src/struct_list.rs b/capnp/src/struct_list.rs index 6d3f149a2..3b29f0178 100644 --- a/capnp/src/struct_list.rs +++ b/capnp/src/struct_list.rs @@ -23,63 +23,105 @@ use core::marker::PhantomData; -use crate::private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, InlineComposite}; -use crate::traits::{FromPointerReader, FromPointerBuilder, - FromStructBuilder, FromStructReader, HasStructSize, - IndexMove, ListIter}; +use crate::private::layout::{ + InlineComposite, ListBuilder, ListReader, PointerBuilder, PointerReader, +}; +use crate::traits::{ + FromPointerBuilder, FromPointerReader, FromStructBuilder, FromStructReader, HasStructSize, + IndexMove, ListIter, +}; use crate::Result; #[derive(Copy, Clone)] -pub struct Owned where T: crate::traits::OwnedStruct { +pub struct Owned +where + T: crate::traits::OwnedStruct, +{ marker: PhantomData, } -impl crate::traits::Owned for Owned where T: crate::traits::OwnedStruct { +impl crate::traits::Owned for Owned +where + T: crate::traits::OwnedStruct, +{ type Reader<'a> = Reader<'a, T>; type Builder<'a> = Builder<'a, T>; } -pub struct Reader<'a, T> where T: crate::traits::OwnedStruct { +pub struct Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ marker: PhantomData, - reader: ListReader<'a> + reader: ListReader<'a>, } -impl <'a, T> Clone for Reader<'a, T> where T: crate::traits::OwnedStruct { +impl<'a, T> Clone for Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ fn clone(&self) -> Reader<'a, T> { - Reader { marker : self.marker, reader : self.reader } + Reader { + marker: self.marker, + reader: self.reader, + } } } -impl <'a, T> Copy for Reader<'a, T> where T: crate::traits::OwnedStruct {} +impl<'a, T> Copy for Reader<'a, T> where T: crate::traits::OwnedStruct {} -impl <'a, T> Reader<'a, T> where T: crate::traits::OwnedStruct { - pub fn len(&self) -> u32 { self.reader.len() } +impl<'a, T> Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ + pub fn len(&self) -> u32 { + self.reader.len() + } pub fn iter(self) -> ListIter, T::Reader<'a>> { ListIter::new(self, self.len()) } } -impl <'a, T> Reader<'a, T> where T: crate::traits::OwnedStruct { - pub fn reborrow(&self) -> Reader<'_, T> { - Reader { reader: self.reader, marker: PhantomData } +impl<'a, T> Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ + pub fn reborrow(&self) -> Reader<'_, T> { + Reader { + reader: self.reader, + marker: PhantomData, + } } } -impl <'a, T> FromPointerReader<'a> for Reader<'a, T> where T: crate::traits::OwnedStruct { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader: reader.get_list(InlineComposite, default)?, - marker: PhantomData }) +impl<'a, T> FromPointerReader<'a> for Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(InlineComposite, default)?, + marker: PhantomData, + }) } } -impl <'a, T> IndexMove> for Reader<'a, T> -where T: crate::traits::OwnedStruct { +impl<'a, T> IndexMove> for Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ fn index_move(&self, index: u32) -> T::Reader<'a> { self.get(index) } } -impl <'a, T> Reader<'a, T> where T: crate::traits::OwnedStruct { +impl<'a, T> Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(self, index: u32) -> T::Reader<'a> { @@ -98,19 +140,30 @@ impl <'a, T> Reader<'a, T> where T: crate::traits::OwnedStruct { } } -impl <'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> where T: crate::traits::OwnedStruct { +impl<'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> +where + T: crate::traits::OwnedStruct, +{ fn into_internal_list_reader(self) -> ListReader<'a> { self.reader } } -pub struct Builder<'a, T> where T: crate::traits::OwnedStruct { +pub struct Builder<'a, T> +where + T: crate::traits::OwnedStruct, +{ marker: PhantomData, - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a, T> Builder<'a, T> where T: crate::traits::OwnedStruct { - pub fn len(&self) -> u32 { self.builder.len() } +impl<'a, T> Builder<'a, T> +where + T: crate::traits::OwnedStruct, +{ + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn into_reader(self) -> Reader<'a, T> { Reader { @@ -123,41 +176,54 @@ impl <'a, T> Builder<'a, T> where T: crate::traits::OwnedStruct { /// struct list are allocated inline: if the source struct is larger than the target struct /// (as can happen if it was created with a newer version of the schema), then it will be /// truncated, losing fields. - pub fn set_with_caveats<'b>(&self, index: u32, value: T::Reader<'b>) - -> Result<()> - where T::Reader<'b>: crate::traits::IntoInternalStructReader<'b> + pub fn set_with_caveats<'b>(&self, index: u32, value: T::Reader<'b>) -> Result<()> + where + T::Reader<'b>: crate::traits::IntoInternalStructReader<'b>, { use crate::traits::IntoInternalStructReader; - self.builder.get_struct_element(index).copy_content_from(&value.into_internal_struct_reader()) + self.builder + .get_struct_element(index) + .copy_content_from(&value.into_internal_struct_reader()) } } -impl <'a, T> Builder<'a, T> where T: crate::traits::OwnedStruct { +impl<'a, T> Builder<'a, T> +where + T: crate::traits::OwnedStruct, +{ pub fn reborrow(&mut self) -> Builder<'_, T> { - Builder { builder: self.builder, marker: PhantomData } + Builder { + builder: self.builder, + marker: PhantomData, + } } - } -impl <'a, T> FromPointerBuilder<'a> for Builder<'a, T> where T: crate::traits::OwnedStruct { +impl<'a, T> FromPointerBuilder<'a> for Builder<'a, T> +where + T: crate::traits::OwnedStruct, +{ fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> { Builder { marker: PhantomData, - builder: builder.init_struct_list( - size, - T::Builder::STRUCT_SIZE) + builder: builder.init_struct_list(size, T::Builder::STRUCT_SIZE), } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { Ok(Builder { marker: PhantomData, - builder: - builder.get_struct_list(T::Builder::STRUCT_SIZE, default)? + builder: builder.get_struct_list(T::Builder::STRUCT_SIZE, default)?, }) } } -impl <'a, T> Builder<'a, T> where T: crate::traits::OwnedStruct { +impl<'a, T> Builder<'a, T> +where + T: crate::traits::OwnedStruct, +{ /// Gets the element at position `index`. Panics if `index` is greater than or /// equal to `len()`. pub fn get(self, index: u32) -> T::Builder<'a> { @@ -169,25 +235,31 @@ impl <'a, T> Builder<'a, T> where T: crate::traits::OwnedStruct { /// is greater than or equal to `len()`. pub fn try_get(self, index: u32) -> Option> { if index < self.len() { - Some(FromStructBuilder::new(self.builder.get_struct_element(index))) + Some(FromStructBuilder::new( + self.builder.get_struct_element(index), + )) } else { None } } } -impl <'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> - where T: crate::traits::OwnedStruct +impl<'a, T> crate::traits::SetPointerBuilder for Reader<'a, T> +where + T: crate::traits::OwnedStruct, { - fn set_pointer_builder<'b>(pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a, T>, - canonicalize: bool) -> Result<()> { + fn set_pointer_builder<'b>( + pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a, T>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize) } } -impl <'a, T> ::core::iter::IntoIterator for Reader<'a, T> - where T: crate::traits::OwnedStruct +impl<'a, T> ::core::iter::IntoIterator for Reader<'a, T> +where + T: crate::traits::OwnedStruct, { type Item = T::Reader<'a>; type IntoIter = ListIter, Self::Item>; diff --git a/capnp/src/text.rs b/capnp/src/text.rs index 1920cb47a..32a1f2853 100644 --- a/capnp/src/text.rs +++ b/capnp/src/text.rs @@ -21,7 +21,7 @@ //! UTF-8 encoded text. -use core::{convert, str, ops}; +use core::{convert, ops, str}; use crate::{Error, Result}; @@ -35,17 +35,21 @@ impl crate::traits::Owned for Owned { pub type Reader<'a> = &'a str; -pub fn new_reader(v : &[u8]) -> Result> { +pub fn new_reader(v: &[u8]) -> Result> { match str::from_utf8(v) { Ok(v) => Ok(v), - Err(e) => Err(Error::failed( - format!("Text contains non-utf8 data: {:?}", e))), + Err(e) => Err(Error::failed(format!( + "Text contains non-utf8 data: {:?}", + e + ))), } } -impl <'a> crate::traits::FromPointerReader<'a> for Reader<'a> { - fn get_from_pointer(reader: &crate::private::layout::PointerReader<'a>, - default: Option<&'a [crate::Word]>) -> Result> { +impl<'a> crate::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &crate::private::layout::PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { reader.get_text(default) } } @@ -55,15 +59,20 @@ pub struct Builder<'a> { pos: usize, } -impl <'a> Builder <'a> { +impl<'a> Builder<'a> { pub fn new(bytes: &mut [u8], pos: u32) -> Result> { if pos != 0 { if let Err(e) = str::from_utf8(bytes) { - return Err(Error::failed( - format!("Text contains non-utf8 data: {:?}", e))) + return Err(Error::failed(format!( + "Text contains non-utf8 data: {:?}", + e + ))); } } - Ok(Builder { bytes, pos: pos as usize }) + Ok(Builder { + bytes, + pos: pos as usize, + }) } pub fn push_ascii(&mut self, ascii: u8) { @@ -74,7 +83,7 @@ impl <'a> Builder <'a> { pub fn push_str(&mut self, string: &str) { let bytes = string.as_bytes(); - self.bytes[self.pos..(self.pos+bytes.len())].copy_from_slice(bytes); + self.bytes[self.pos..(self.pos + bytes.len())].copy_from_slice(bytes); self.pos += bytes.len(); } @@ -86,7 +95,7 @@ impl <'a> Builder <'a> { } } -impl <'a> ops::Deref for Builder <'a> { +impl<'a> ops::Deref for Builder<'a> { type Target = str; fn deref(&self) -> &str { str::from_utf8(self.bytes) @@ -94,35 +103,38 @@ impl <'a> ops::Deref for Builder <'a> { } } -impl <'a> ops::DerefMut for Builder <'a> { +impl<'a> ops::DerefMut for Builder<'a> { fn deref_mut(&mut self) -> &mut str { str::from_utf8_mut(self.bytes) .expect("text::Builder contents are checked for utf8-validity upon construction") } } -impl <'a> convert::AsRef for Builder<'a> { +impl<'a> convert::AsRef for Builder<'a> { fn as_ref(&self) -> &str { str::from_utf8(self.bytes) .expect("text::Builder contents are checked for utf8-validity upon construction") } } -impl <'a> crate::traits::FromPointerBuilder<'a> for Builder<'a> { +impl<'a> crate::traits::FromPointerBuilder<'a> for Builder<'a> { fn init_pointer(builder: crate::private::layout::PointerBuilder<'a>, size: u32) -> Builder<'a> { builder.init_text(size) } - fn get_from_pointer(builder: crate::private::layout::PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: crate::private::layout::PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { builder.get_text(default) } } -impl <'a> crate::traits::SetPointerBuilder for Reader<'a> { - fn set_pointer_builder<'b>(pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a>, - _canonicalize: bool) - -> Result<()> - { +impl<'a> crate::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder<'b>( + pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a>, + _canonicalize: bool, + ) -> Result<()> { pointer.set_text(value); Ok(()) } diff --git a/capnp/src/text_list.rs b/capnp/src/text_list.rs index 9eccfe9e9..61aca99f4 100644 --- a/capnp/src/text_list.rs +++ b/capnp/src/text_list.rs @@ -21,8 +21,8 @@ //! List of strings containing UTF-8 encoded text. -use crate::traits::{FromPointerReader, FromPointerBuilder, IndexMove, ListIter}; use crate::private::layout::{ListBuilder, ListReader, Pointer, PointerBuilder, PointerReader}; +use crate::traits::{FromPointerBuilder, FromPointerReader, IndexMove, ListIter}; use crate::Result; #[derive(Copy, Clone)] @@ -35,46 +35,53 @@ impl crate::traits::Owned for Owned { #[derive(Clone, Copy)] pub struct Reader<'a> { - reader: ListReader<'a> + reader: ListReader<'a>, } -impl <'a> Reader<'a> { - pub fn new<'b>(reader : ListReader<'b>) -> Reader<'b> { +impl<'a> Reader<'a> { + pub fn new<'b>(reader: ListReader<'b>) -> Reader<'b> { Reader::<'b> { reader } } - pub fn len(&self) -> u32 { self.reader.len() } + pub fn len(&self) -> u32 { + self.reader.len() + } - pub fn iter(self) -> ListIter, Result>>{ + pub fn iter(self) -> ListIter, Result>> { let l = self.len(); ListIter::new(self, l) } } -impl <'a> FromPointerReader<'a> for Reader<'a> { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result> { - Ok(Reader { reader : reader.get_list(Pointer, default)? }) +impl<'a> FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { + Ok(Reader { + reader: reader.get_list(Pointer, default)?, + }) } } -impl <'a> IndexMove>> for Reader<'a>{ - fn index_move(&self, index : u32) -> Result> { +impl<'a> IndexMove>> for Reader<'a> { + fn index_move(&self, index: u32) -> Result> { self.get(index) } } -impl <'a> Reader<'a> { +impl<'a> Reader<'a> { /// Gets the `text::Reader` at position `index`. Panics if `index` is /// greater than or equal to `len()`. - pub fn get(self, index : u32) -> Result> { - assert!(index < self.len()); + pub fn get(self, index: u32) -> Result> { + assert!(index < self.len()); self.reader.get_pointer_element(index).get_text(None) } /// Gets the `text::Reader` at position `index`. Returns `None` if `index` /// is greater than or equal to `len()`. - pub fn try_get(self, index : u32) -> Option>> { - if index < self.len() { + pub fn try_get(self, index: u32) -> Option>> { + if index < self.len() { Some(self.reader.get_pointer_element(index).get_text(None)) } else { None @@ -82,56 +89,67 @@ impl <'a> Reader<'a> { } } -impl <'a> crate::traits::IntoInternalListReader<'a> for Reader<'a> { +impl<'a> crate::traits::IntoInternalListReader<'a> for Reader<'a> { fn into_internal_list_reader(self) -> ListReader<'a> { self.reader } } pub struct Builder<'a> { - builder: ListBuilder<'a> + builder: ListBuilder<'a>, } -impl <'a> Builder<'a> { - pub fn new(builder : ListBuilder<'a>) -> Builder<'a> { +impl<'a> Builder<'a> { + pub fn new(builder: ListBuilder<'a>) -> Builder<'a> { Builder { builder } } - pub fn len(&self) -> u32 { self.builder.len() } + pub fn len(&self) -> u32 { + self.builder.len() + } pub fn set(&mut self, index: u32, value: crate::text::Reader) { assert!(index < self.len()); - self.builder.reborrow().get_pointer_element(index).set_text(value); + self.builder + .reborrow() + .get_pointer_element(index) + .set_text(value); } pub fn into_reader(self) -> Reader<'a> { - Reader { reader: self.builder.into_reader() } + Reader { + reader: self.builder.into_reader(), + } } pub fn reborrow<'b>(&'b mut self) -> Builder<'b> { - Builder::<'b> { builder: self.builder.reborrow() } + Builder::<'b> { + builder: self.builder.reborrow(), + } } } - -impl <'a> FromPointerBuilder<'a> for Builder<'a> { +impl<'a> FromPointerBuilder<'a> for Builder<'a> { fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a> { Builder { - builder: builder.init_list(Pointer, size) + builder: builder.init_list(Pointer, size), } } - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result> { + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result> { Ok(Builder { - builder: builder.get_list(Pointer, default)? + builder: builder.get_list(Pointer, default)?, }) } } -impl <'a> Builder<'a> { +impl<'a> Builder<'a> { /// Gets the `text::Builder` at position `index`. Panics if `index` is /// greater than or equal to `len()`. pub fn get(self, index: u32) -> Result> { - assert!(index < self.len()); + assert!(index < self.len()); self.builder.get_pointer_element(index).get_text(None) } @@ -146,15 +164,17 @@ impl <'a> Builder<'a> { } } -impl <'a> crate::traits::SetPointerBuilder for Reader<'a> { - fn set_pointer_builder<'b>(pointer: crate::private::layout::PointerBuilder<'b>, - value: Reader<'a>, - canonicalize: bool) -> Result<()> { +impl<'a> crate::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder<'b>( + pointer: crate::private::layout::PointerBuilder<'b>, + value: Reader<'a>, + canonicalize: bool, + ) -> Result<()> { pointer.set_list(&value.reader, canonicalize) } } -impl <'a> ::core::iter::IntoIterator for Reader<'a> { +impl<'a> ::core::iter::IntoIterator for Reader<'a> { type Item = Result>; type IntoIter = ListIter, Self::Item>; diff --git a/capnp/src/traits.rs b/capnp/src/traits.rs index 6571230e0..bdcd14ddf 100644 --- a/capnp/src/traits.rs +++ b/capnp/src/traits.rs @@ -19,9 +19,10 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -use crate::{Result}; -use crate::private::layout::{CapTable, ListReader, StructReader, StructBuilder, StructSize, - PointerBuilder, PointerReader}; +use crate::private::layout::{ + CapTable, ListReader, PointerBuilder, PointerReader, StructBuilder, StructReader, StructSize, +}; +use crate::Result; use core::marker::PhantomData; @@ -45,8 +46,11 @@ pub trait IntoInternalListReader<'a> { fn into_internal_list_reader(self) -> ListReader<'a>; } -pub trait FromPointerReader<'a> : Sized { - fn get_from_pointer(reader: &PointerReader<'a>, default: Option<&'a [crate::Word]>) -> Result; +pub trait FromPointerReader<'a>: Sized { + fn get_from_pointer( + reader: &PointerReader<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result; } /// A trait to encode relationships readers and builders. @@ -73,13 +77,20 @@ pub trait Pipelined { type Pipeline; } -pub trait FromPointerBuilder<'a> : Sized { +pub trait FromPointerBuilder<'a>: Sized { fn init_pointer(builder: PointerBuilder<'a>, length: u32) -> Self; - fn get_from_pointer(builder: PointerBuilder<'a>, default: Option<&'a [crate::Word]>) -> Result; + fn get_from_pointer( + builder: PointerBuilder<'a>, + default: Option<&'a [crate::Word]>, + ) -> Result; } pub trait SetPointerBuilder { - fn set_pointer_builder(builder: PointerBuilder<'_>, from: Self, canonicalize: bool) -> Result<()>; + fn set_pointer_builder( + builder: PointerBuilder<'_>, + from: Self, + canonicalize: bool, + ) -> Result<()>; } pub trait Imbue<'a> { @@ -103,7 +114,7 @@ pub trait ToU16 { fn to_u16(self) -> u16; } -pub trait FromU16 : Sized { +pub trait FromU16: Sized { fn from_u16(value: u16) -> ::core::result::Result; } @@ -118,13 +129,18 @@ pub struct ListIter { size: u32, } -impl ListIter{ +impl ListIter { pub fn new(list: T, size: u32) -> ListIter { - ListIter { list, index: 0, size, marker: PhantomData } + ListIter { + list, + index: 0, + size, + marker: PhantomData, + } } } -impl > ::core::iter::Iterator for ListIter { +impl> ::core::iter::Iterator for ListIter { type Item = U; fn next(&mut self) -> ::core::option::Option { if self.index < self.size { @@ -136,12 +152,12 @@ impl > ::core::iter::Iterator for ListIter { } } - fn size_hint(&self) -> (usize, Option){ + fn size_hint(&self) -> (usize, Option) { (self.size as usize, Some(self.size as usize)) } - fn nth(&mut self, p: usize) -> Option{ - if self.index + (p as u32) < self.size { + fn nth(&mut self, p: usize) -> Option { + if self.index + (p as u32) < self.size { self.index += p as u32; let result = self.list.index_move(self.index); self.index += 1; @@ -153,13 +169,13 @@ impl > ::core::iter::Iterator for ListIter { } } -impl > ::core::iter::ExactSizeIterator for ListIter{ - fn len(&self) -> usize{ +impl> ::core::iter::ExactSizeIterator for ListIter { + fn len(&self) -> usize { self.size as usize } } -impl > ::core::iter::DoubleEndedIterator for ListIter{ +impl> ::core::iter::DoubleEndedIterator for ListIter { fn next_back(&mut self) -> ::core::option::Option { if self.size > self.index { self.size -= 1; diff --git a/capnp/tests/canonicalize.rs b/capnp/tests/canonicalize.rs index 451762e30..c0404ad44 100644 --- a/capnp/tests/canonicalize.rs +++ b/capnp/tests/canonicalize.rs @@ -23,9 +23,7 @@ use capnp::message; #[test] fn canonicalize_succeeds_on_null_message() { - let segment: &[capnp::Word] = &[ - capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - ]; + let segment: &[capnp::Word] = &[capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)]; let segments = &[capnp::Word::words_to_bytes(segment)]; let segment_array = message::SegmentArray::new(segments); @@ -41,13 +39,10 @@ fn dont_truncate_struct_too_far() { let segment: &[capnp::Word] = &[ // Struct pointer, body immediately follows, three data words capnp::word(0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00), - // First data word capnp::word(0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11), - // Second data word, all zero except most significant bit capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80), - // Third data word, all zero capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), ]; @@ -68,25 +63,19 @@ fn dont_truncate_struct_too_far() { assert_eq!(&canonicalized[..], canonical_segment); } - #[test] fn dont_truncate_struct_list_too_far() { let segment: &[capnp::Word] = &[ // Struct pointer, body immediately follows, one pointer capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00), - // List pointer, no offset, inline composite, three words long capnp::word(0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00), - // Tag word, list has one element with three data words and no pointers capnp::word(0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00), - // First data word capnp::word(0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22), - // Second data word, all zero except most significant bit capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80), - // Third data word, all zero capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), ]; @@ -114,13 +103,10 @@ fn canonical_non_null_empty_struct_field() { let segment: &[capnp::Word] = &[ // Struct pointer, body immediately follows, two pointer fields, no data. capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00), - // First pointer field, struct, offset of 1, data size 1, no pointers. capnp::word(0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - // Non-null pointer to empty struct. capnp::word(0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00), - // Body of struct filled with non-zero data. capnp::word(0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee), ]; @@ -136,14 +122,11 @@ fn pointer_to_empty_struct_preorder_not_canonical() { let segment: &[capnp::Word] = &[ // Struct pointer, body immediately follows, two pointer fields, no data. capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00), - // First pointer field, struct, offset of 1, data size 1, no pointers. capnp::word(0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - // Non-null pointer to empty struct. Offset puts it in "preorder". Would need to have // an offset of -1 to be canonical. capnp::word(0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - // Body of struct filled with non-zero data. capnp::word(0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee), ]; @@ -159,16 +142,12 @@ fn is_canonical_requires_pointer_preorder() { let segment: &[capnp::Word] = &[ //Struct pointer, data immediately follows, two pointer fields, no data capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00), - //Pointer field 1, pointing to the last entry, data size 1, no pointer capnp::word(0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - //Pointer field 2, pointing to the next entry, data size 2, no pointer capnp::word(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - //Data for field 2 capnp::word(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07), - //Data for field 1 capnp::word(0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00), ]; @@ -184,10 +163,8 @@ fn is_canonical_requires_dense_packing() { let segment: &[capnp::Word] = &[ //Struct pointer, data after a gap capnp::word(0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - //The gap capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - //Data for field 1 capnp::word(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07), ]; @@ -208,13 +185,14 @@ fn simple_multisegment_message() { let segment1: &[capnp::Word] = &[ //Struct pointer (needed to make the far pointer legal) capnp::word(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - //Dummy data capnp::word(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07), ]; - let segments = &[capnp::Word::words_to_bytes(segment0), - capnp::Word::words_to_bytes(segment1)]; + let segments = &[ + capnp::Word::words_to_bytes(segment0), + capnp::Word::words_to_bytes(segment1), + ]; let segment_array = message::SegmentArray::new(segments); let message = message::Reader::new(segment_array, Default::default()); assert!(!message.is_canonical().unwrap()); @@ -236,12 +214,12 @@ fn multisegment_only_first_segment_used() { capnp::word(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07), ]; - let segment1: &[capnp::Word] = &[ - capnp::word(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - ]; + let segment1: &[capnp::Word] = &[capnp::word(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00)]; - let segments = &[capnp::Word::words_to_bytes(segment0), - capnp::Word::words_to_bytes(segment1)]; + let segments = &[ + capnp::Word::words_to_bytes(segment0), + capnp::Word::words_to_bytes(segment1), + ]; let segment_array = message::SegmentArray::new(segments); let message = message::Reader::new(segment_array, Default::default()); assert!(!message.is_canonical().unwrap()); @@ -260,7 +238,6 @@ fn is_canonical_requires_truncation_of_0_valued_struct_fields() { let segment: &[capnp::Word] = &[ //Struct pointer, data immediately follows capnp::word(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - //Default data value, should have been truncated capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), ]; @@ -276,10 +253,8 @@ fn is_canonical_rejects_unused_trailing_words() { let segment: &[capnp::Word] = &[ // Struct pointer, data in next word capnp::word(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - // Data section of struct capnp::word(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07), - // Trailing zero word capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), ]; @@ -295,10 +270,8 @@ fn empty_inline_composite_list_of_0_sized_structs() { let segment: &[capnp::Word] = &[ // Struct pointer, pointer in next word capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00), - // List pointer, inline composite, zero words long capnp::word(0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00), - // Tag word capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), ]; @@ -317,10 +290,8 @@ fn inline_composite_list_with_void_list() { let segment: &[capnp::Word] = &[ // List, inline composite capnp::word(0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00), - // One element, one pointer capnp::word(0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00), - // List of 1 VOID capnp::word(0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00), ]; @@ -339,21 +310,16 @@ fn is_canonical_rejects_inline_composite_list_with_inaccurate_word_length() { let segment: &[capnp::Word] = &[ // Struct pointer, no offset, pointer section has two entries capnp::word(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00), - // List pointer, offset of one, inline composite, two words long // (The list only needs to be one word long to hold its actual elements; // therefore this message is not canonical.) capnp::word(0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00), - // Struct pointer, offset two, data section has one word capnp::word(0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - // Tag word, struct, one element, one word data section capnp::word(0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), - // Data section of struct element of list capnp::word(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07), - // Data section of struct field in top-level struct capnp::word(0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00), ]; @@ -426,7 +392,6 @@ fn list_padding_must_be_zero() { let segment: &[capnp::Word] = &[ // List of three single-byte elements capnp::word(0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00), - // Fourth byte is also nonzero, so this list is not canonical capnp::word(0x01, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00), ]; @@ -443,7 +408,6 @@ fn list_padding_must_be_zero() { let canonical_message = message::Reader::new(canonical_segment_array, Default::default()); assert!(canonical_message.is_canonical().unwrap()); - let expected_canonical_words: &[capnp::Word] = &[ capnp::word(0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00), capnp::word(0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00), @@ -457,7 +421,6 @@ fn bit_list_padding_must_be_zero() { let segment: &[capnp::Word] = &[ // List of eleven single-bit elements capnp::word(0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00), - // Twelfth bit is nonzero, so list is not canonical capnp::word(0xee, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), ]; @@ -474,7 +437,6 @@ fn bit_list_padding_must_be_zero() { let canonical_message = message::Reader::new(canonical_segment_array, Default::default()); assert!(canonical_message.is_canonical().unwrap()); - let expected_canonical_words: &[capnp::Word] = &[ capnp::word(0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00), capnp::word(0xee, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), @@ -514,10 +476,8 @@ fn far_pointer_to_same_segment() { let segment: &[capnp::Word] = &[ // Far pointer to this same segment. Landing pad is two words, offset of one. capnp::word(0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - // Landing pad. Again, points back to this same segment. capnp::word(0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - // Tag word, describing struct with 2-word data section. capnp::word(0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00), ]; diff --git a/capnpc/src/codegen.rs b/capnpc/src/codegen.rs index 5c1f03ed9..69c008386 100644 --- a/capnpc/src/codegen.rs +++ b/capnpc/src/codegen.rs @@ -20,17 +20,17 @@ // THE SOFTWARE. use std::collections; -use std::collections::{HashMap,HashSet}; +use std::collections::{HashMap, HashSet}; use std::path::{Path, PathBuf}; use capnp; use capnp::Error; -use crate::{convert_io_err}; +use self::FormattedText::{BlankLine, Branch, Indent, Line}; +use crate::codegen_types::{do_branding, Leaf, RustNodeInfo, RustTypeInfo, TypeParameterTexts}; +use crate::convert_io_err; use crate::pointer_constants::generate_pointer_constant; use crate::schema_capnp; -use crate::codegen_types::{ Leaf, RustTypeInfo, RustNodeInfo, TypeParameterTexts, do_branding }; -use self::FormattedText::{Indent, Line, Branch, BlankLine}; /// An invocation of the capnpc-rust code generation plugin. pub struct CodeGenerationCommand { @@ -51,7 +51,8 @@ impl CodeGenerationCommand { /// Sets the output directory. pub fn output_directory

(&mut self, path: P) -> &mut Self - where P: AsRef + where + P: AsRef, { self.output_directory = path.as_ref().to_path_buf(); self @@ -61,15 +62,15 @@ impl CodeGenerationCommand { /// add the generated code. /// /// This option can be overridden by the `parentModule` annotation defined in `rust.capnp`. - pub fn default_parent_module(&mut self, default_parent_module: Vec) -> &mut Self - { + pub fn default_parent_module(&mut self, default_parent_module: Vec) -> &mut Self { self.default_parent_module = default_parent_module; self } /// Sets the raw code generator request output path. pub fn raw_code_generator_request_path

(&mut self, path: P) -> &mut Self - where P: AsRef + where + P: AsRef, { self.raw_code_generator_request_path = Some(path.as_ref().to_path_buf()); self @@ -77,14 +78,21 @@ impl CodeGenerationCommand { /// Generates Rust code according to a `schema_capnp::code_generator_request` read from `inp`. pub fn run(&mut self, inp: T) -> ::capnp::Result<()> - where T: std::io::Read + where + T: std::io::Read, { use capnp::serialize; use std::io::Write; - let message = serialize::read_message(ReadWrapper { inner: inp }, capnp::message::ReaderOptions::new())?; + let message = serialize::read_message( + ReadWrapper { inner: inp }, + capnp::message::ReaderOptions::new(), + )?; - let gen = GeneratorContext::new_with_default_parent_module(&self.default_parent_module[..], &message)?; + let gen = GeneratorContext::new_with_default_parent_module( + &self.default_parent_module[..], + &message, + )?; for requested_file in gen.request.get_requested_files()?.iter() { let id = requested_file.get_id(); @@ -98,12 +106,16 @@ impl CodeGenerationCommand { let root_name = path_to_stem_string(&filepath)?.replace("-", "_"); filepath.set_file_name(&format!("{}_capnp.rs", root_name)); - let lines = Branch(vec!( - Line("// @generated by the capnpc-rust plugin to the Cap'n Proto schema compiler.".to_string()), + let lines = Branch(vec![ + Line( + "// @generated by the capnpc-rust plugin to the Cap'n Proto schema compiler." + .to_string(), + ), Line("// DO NOT EDIT.".to_string()), Line(format!("// source: {}", requested_file.get_filename()?)), BlankLine, - generate_node(&gen, id, &root_name, None)?)); + generate_node(&gen, id, &root_name, None)?, + ]); let text = stringify(&lines); @@ -123,16 +135,26 @@ impl CodeGenerationCommand { writer.write_all(text.as_bytes()).map_err(convert_io_err)?; } Err(e) => { - let _ = writeln!(&mut ::std::io::stderr(), - "could not open file {:?} for writing: {}", filepath, e); + let _ = writeln!( + &mut ::std::io::stderr(), + "could not open file {:?} for writing: {}", + filepath, + e + ); return Err(convert_io_err(e)); } } } if let Some(raw_code_generator_request) = &self.raw_code_generator_request_path { - let raw_code_generator_request_file = ::std::fs::File::create(raw_code_generator_request).map_err(convert_io_err)?; - serialize::write_message_segments(WriteWrapper{ inner: raw_code_generator_request_file }, &message.into_segments())?; + let raw_code_generator_request_file = + ::std::fs::File::create(raw_code_generator_request).map_err(convert_io_err)?; + serialize::write_message_segments( + WriteWrapper { + inner: raw_code_generator_request_file, + }, + &message.into_segments(), + )?; } Ok(()) @@ -145,24 +167,22 @@ pub struct GeneratorContext<'a> { pub scope_map: collections::hash_map::HashMap>, } -impl <'a> GeneratorContext<'a> { +impl<'a> GeneratorContext<'a> { pub fn new( - message:&'a capnp::message::Reader) - -> ::capnp::Result> - { + message: &'a capnp::message::Reader, + ) -> ::capnp::Result> { GeneratorContext::new_with_default_parent_module(&[], message) } fn new_with_default_parent_module( default_parent_module: &[String], - message:&'a capnp::message::Reader) - -> ::capnp::Result> - { + message: &'a capnp::message::Reader, + ) -> ::capnp::Result> { let mut default_parent_module_scope = vec!["crate".to_string()]; default_parent_module_scope.extend_from_slice(default_parent_module); let mut gen = GeneratorContext { - request : message.get_root()?, + request: message.get_root()?, node_map: collections::hash_map::HashMap::>::new(), scope_map: collections::hash_map::HashMap::>::new(), }; @@ -179,23 +199,28 @@ impl <'a> GeneratorContext<'a> { let importpath = ::std::path::Path::new(import.get_name()?); let root_name: String = format!( "{}_capnp", - path_to_stem_string(importpath)?.replace("-", "_")); - populate_scope_map(&gen.node_map, - &mut gen.scope_map, - default_parent_module_scope.clone(), - root_name, - NameKind::Verbatim, - import.get_id())?; + path_to_stem_string(importpath)?.replace("-", "_") + ); + populate_scope_map( + &gen.node_map, + &mut gen.scope_map, + default_parent_module_scope.clone(), + root_name, + NameKind::Verbatim, + import.get_id(), + )?; } let root_name = path_to_stem_string(requested_file.get_filename()?)?; let root_mod = format!("{}_capnp", root_name.replace("-", "_")); - populate_scope_map(&gen.node_map, - &mut gen.scope_map, - default_parent_module_scope.clone(), - root_mod, - NameKind::Verbatim, - id)?; + populate_scope_map( + &gen.node_map, + &mut gen.scope_map, + default_parent_module_scope.clone(), + root_mod, + NameKind::Verbatim, + id, + )?; } Ok(gen) } @@ -206,20 +231,21 @@ impl <'a> GeneratorContext<'a> { Some(v) => match v.last() { None => Err(Error::failed(format!("node has no scope: {}", id))), Some(n) => Ok(n), - } + }, } } } fn path_to_stem_string>(path: P) -> ::capnp::Result { match path.as_ref().file_stem() { - None => Err(Error::failed(format!("file has no stem: {:?}", path.as_ref()))), - Some(stem) => { - match stem.to_owned().into_string() { - Err(os_string) => Err(Error::failed(format!("bad filename: {:?}", os_string))), - Ok(s) => Ok(s), - } - } + None => Err(Error::failed(format!( + "file has no stem: {:?}", + path.as_ref() + ))), + Some(stem) => match stem.to_owned().into_string() { + Err(os_string) => Err(Error::failed(format!("bad filename: {:?}", os_string))), + Ok(s) => Ok(s), + }, } } @@ -250,7 +276,9 @@ fn camel_to_snake_case(s: &str) -> String { fn capitalize_first_letter(s: &str) -> String { let mut result_chars: Vec = Vec::new(); - for c in s.chars() { result_chars.push(c) } + for c in s.chars() { + result_chars.push(c) + } result_chars[0] = result_chars[0].to_ascii_uppercase(); result_chars.into_iter().collect() } @@ -296,29 +324,29 @@ pub enum FormattedText { Indent(Box), Branch(Vec), Line(String), - BlankLine + BlankLine, } -fn to_lines(ft : &FormattedText, indent : usize) -> Vec { +fn to_lines(ft: &FormattedText, indent: usize) -> Vec { match *ft { - Indent (ref ft) => { + Indent(ref ft) => { return to_lines(&**ft, indent + 1); } - Branch (ref fts) => { + Branch(ref fts) => { let mut result = Vec::new(); for ft in fts.iter() { for line in to_lines(ft, indent).iter() { - result.push(line.clone()); // TODO there's probably a better way to do this. + result.push(line.clone()); // TODO there's probably a better way to do this. } } return result; } Line(ref s) => { - let mut s1 : String = ::std::iter::repeat(' ').take(indent * 2).collect(); + let mut s1: String = ::std::iter::repeat(' ').take(indent * 2).collect(); s1.push_str(s); - return vec!(s1.to_string()); + return vec![s1.to_string()]; } - BlankLine => return vec!("".to_string()) + BlankLine => return vec!["".to_string()], } } @@ -328,18 +356,13 @@ fn stringify(ft: &FormattedText) -> String { result.to_string() } -const RUST_KEYWORDS : [&'static str; 53] = - ["abstract", "alignof", "as", "be", "become", - "box", "break", "const", "continue", "crate", - "do", "else", "enum", "extern", "false", - "final", "fn", "for", "if", "impl", - "in", "let", "loop", "macro", "match", - "mod", "move", "mut", "offsetof", "once", - "override", "priv", "proc", "pub", "pure", - "ref", "return", "self", "sizeof", "static", - "struct", "super", "trait", "true", "type", - "typeof", "unsafe", "unsized", "use", "virtual", - "where", "while", "yield"]; +const RUST_KEYWORDS: [&'static str; 53] = [ + "abstract", "alignof", "as", "be", "become", "box", "break", "const", "continue", "crate", + "do", "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", "let", + "loop", "macro", "match", "mod", "move", "mut", "offsetof", "once", "override", "priv", "proc", + "pub", "pure", "ref", "return", "self", "sizeof", "static", "struct", "super", "trait", "true", + "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield", +]; fn module_name(camel_case: &str) -> String { let mut name = camel_to_snake_case(camel_case); @@ -358,13 +381,16 @@ fn name_annotation_value(annotation: schema_capnp::annotation::Reader) -> capnp: let name = t?; for c in name.chars() { if !(c == '_' || c.is_alphanumeric()) { - return Err(capnp::Error::failed( - format!("rust.name annotation value must only contain alphanumeric characters and '_'"))) + return Err(capnp::Error::failed(format!( + "rust.name annotation value must only contain alphanumeric characters and '_'" + ))); } } Ok(name) } else { - Err(capnp::Error::failed(format!("expected rust.name annotation value to be of type Text"))) + Err(capnp::Error::failed(format!( + "expected rust.name annotation value to be of type Text" + ))) } } @@ -391,7 +417,9 @@ fn get_parent_module(annotation: schema_capnp::annotation::Reader) -> capnp::Res let module = t?; Ok(module.split("::").map(|x| x.to_string()).collect()) } else { - Err(capnp::Error::failed(format!("expected rust.parentModule annotation value to be of type Text"))) + Err(capnp::Error::failed(format!( + "expected rust.parentModule annotation value to be of type Text" + ))) } } @@ -410,14 +438,19 @@ fn capnp_name_to_rust_name(capnp_name: &str, name_kind: NameKind) -> String { } } -fn populate_scope_map(node_map: &collections::hash_map::HashMap, - scope_map: &mut collections::hash_map::HashMap>, - mut ancestor_scope_names: Vec, - mut current_node_name: String, - current_name_kind: NameKind, - node_id: u64) -> ::capnp::Result<()> { +fn populate_scope_map( + node_map: &collections::hash_map::HashMap, + scope_map: &mut collections::hash_map::HashMap>, + mut ancestor_scope_names: Vec, + mut current_node_name: String, + current_name_kind: NameKind, + node_id: u64, +) -> ::capnp::Result<()> { // unused nodes in imported files might be omitted from the node map - let node_reader = match node_map.get(&node_id) { Some(node) => node, None => return Ok(()), }; + let node_reader = match node_map.get(&node_id) { + Some(node) => node, + None => return Ok(()), + }; for annotation in node_reader.get_annotations()?.iter() { if annotation.get_id() == NAME_ANNOTATION_ID { @@ -429,35 +462,40 @@ fn populate_scope_map(node_map: &collections::hash_map::HashMap {} - Some(node_reader) => { - match node_reader.which() { - Ok(schema_capnp::node::Enum(_enum_reader)) => { - populate_scope_map(node_map, - scope_map, - scope_names.clone(), - nested_node.get_name()?.to_string(), - NameKind::Verbatim, - nested_node_id)?; - } - _ => { - populate_scope_map(node_map, - scope_map, - scope_names.clone(), - nested_node.get_name()?.to_string(), - NameKind::Module, - nested_node_id)?; - } + Some(node_reader) => match node_reader.which() { + Ok(schema_capnp::node::Enum(_enum_reader)) => { + populate_scope_map( + node_map, + scope_map, + scope_names.clone(), + nested_node.get_name()?.to_string(), + NameKind::Verbatim, + nested_node_id, + )?; } - } + _ => { + populate_scope_map( + node_map, + scope_map, + scope_names.clone(), + nested_node.get_name()?.to_string(), + NameKind::Module, + nested_node_id, + )?; + } + }, } } @@ -467,18 +505,20 @@ fn populate_scope_map(node_map: &collections::hash_map::HashMap { - populate_scope_map(node_map, - scope_map, - scope_names.clone(), - get_field_name(field)?.to_string(), - NameKind::Module, - group.get_type_id())?; + populate_scope_map( + node_map, + scope_map, + scope_names.clone(), + get_field_name(field)?.to_string(), + NameKind::Module, + group.get_type_id(), + )?; } _ => {} } } } - _ => { } + _ => {} } Ok(()) } @@ -486,10 +526,15 @@ fn populate_scope_map(node_map: &collections::hash_map::HashMap ::capnp::Result> { use crate::schema_capnp::value; match value.which()? { - value::Bool(false) | - value::Int8(0) | value::Int16(0) | value::Int32(0) | - value::Int64(0) | value::Uint8(0) | value::Uint16(0) | - value::Uint32(0) | value::Uint64(0) => Ok(None), + value::Bool(false) + | value::Int8(0) + | value::Int16(0) + | value::Int32(0) + | value::Int64(0) + | value::Uint8(0) + | value::Uint16(0) + | value::Uint32(0) + | value::Uint64(0) => Ok(None), value::Bool(true) => Ok(Some(format!("true"))), value::Int8(i) => Ok(Some(i.to_string())), @@ -500,23 +545,22 @@ fn prim_default(value: &schema_capnp::value::Reader) -> ::capnp::Result Ok(Some(i.to_string())), value::Uint32(i) => Ok(Some(i.to_string())), value::Uint64(i) => Ok(Some(i.to_string())), - value::Float32(f) => - match f.classify() { - ::std::num::FpCategory::Zero => Ok(None), - _ => Ok(Some(format!("{}u32", f.to_bits().to_string()))) - }, - value::Float64(f) => - match f.classify() { - ::std::num::FpCategory::Zero => Ok(None), - _ => Ok(Some(format!("{}u64", f.to_bits().to_string()))) - }, - _ => Err(Error::failed("Non-primitive value found where primitive was expected.".to_string())), + value::Float32(f) => match f.classify() { + ::std::num::FpCategory::Zero => Ok(None), + _ => Ok(Some(format!("{}u32", f.to_bits().to_string()))), + }, + value::Float64(f) => match f.classify() { + ::std::num::FpCategory::Zero => Ok(None), + _ => Ok(Some(format!("{}u64", f.to_bits().to_string()))), + }, + _ => Err(Error::failed( + "Non-primitive value found where primitive was expected.".to_string(), + )), } } // Gets the full list ordered of generic parameters for a node. Outer scopes come first. -fn get_params(gen: &GeneratorContext, - mut node_id: u64) -> ::capnp::Result> { +fn get_params(gen: &GeneratorContext, mut node_id: u64) -> ::capnp::Result> { let mut result = Vec::new(); while node_id != 0 { @@ -537,11 +581,12 @@ fn get_params(gen: &GeneratorContext, // // Returns (type, getter body, default_decl) // -pub fn getter_text(gen: &GeneratorContext, - field: &schema_capnp::field::Reader, - is_reader: bool, - is_fn: bool) - -> ::capnp::Result<(String, FormattedText, Option)> { +pub fn getter_text( + gen: &GeneratorContext, + field: &schema_capnp::field::Reader, + is_reader: bool, + is_fn: bool, +) -> ::capnp::Result<(String, FormattedText, Option)> { use crate::schema_capnp::*; match field.which()? { @@ -577,15 +622,33 @@ pub fn getter_text(gen: &GeneratorContext, let mut default_decl = None; let offset = reg_field.get_offset() as usize; let module_string = if is_reader { "Reader" } else { "Builder" }; - let module = if is_reader { Leaf::Reader("'a") } else { Leaf::Builder("'a") }; + let module = if is_reader { + Leaf::Reader("'a") + } else { + Leaf::Builder("'a") + }; let member = camel_to_snake_case(&*format!("{}", module_string)); - fn primitive_case(typ: &str, member:String, - offset: usize, default: T, zero: T) -> FormattedText { + fn primitive_case( + typ: &str, + member: String, + offset: usize, + default: T, + zero: T, + ) -> FormattedText { if default == zero { - Line(format!("self.{}.get_data_field::<{}>({})", member, typ, offset)) + Line(format!( + "self.{}.get_data_field::<{}>({})", + member, typ, offset + )) } else { - Line(format!("self.{}.get_data_field_mask::<{typ}>({}, {})", member, offset, default, typ=typ)) + Line(format!( + "self.{}.get_data_field_mask::<{typ}>({}, {})", + member, + offset, + default, + typ = typ + )) } } @@ -593,13 +656,19 @@ pub fn getter_text(gen: &GeneratorContext, let typ = raw_type.type_string(gen, module)?; let default_value = reg_field.get_default_value()?; let default = default_value.which()?; - let default_name = format!("DEFAULT_{}", snake_to_upper_case(&camel_to_snake_case(get_field_name(*field)?))); + let default_name = format!( + "DEFAULT_{}", + snake_to_upper_case(&camel_to_snake_case(get_field_name(*field)?)) + ); let mut result_type = match raw_type.which()? { type_::Enum(_) => format!("::core::result::Result<{},::capnp::NotInSchema>", typ), type_::AnyPointer(_) if !raw_type.is_parameter()? => typ.clone(), type_::Interface(_) => { - format!("::capnp::Result<{}>", raw_type.type_string(gen, Leaf::Client)?) + format!( + "::capnp::Result<{}>", + raw_type.type_string(gen, Leaf::Client)? + ) } _ if raw_type.is_prim()? => typ.clone(), _ => format!("::capnp::Result<{}>", typ), @@ -700,14 +769,15 @@ pub fn getter_text(gen: &GeneratorContext, } fn zero_fields_of_group(gen: &GeneratorContext, node_id: u64) -> ::capnp::Result { - use crate::schema_capnp::{node, field, type_}; + use crate::schema_capnp::{field, node, type_}; match gen.node_map[&node_id].which()? { node::Struct(st) => { let mut result = Vec::new(); if st.get_discriminant_count() != 0 { - result.push( - Line(format!("self.builder.set_data_field::({}, 0);", - st.get_discriminant_offset()))); + result.push(Line(format!( + "self.builder.set_data_field::({}, 0);", + st.get_discriminant_offset() + ))); } let fields = st.get_fields()?; for field in fields.iter() { @@ -757,14 +827,18 @@ fn zero_fields_of_group(gen: &GeneratorContext, node_id: u64) -> ::capnp::Result } Ok(Branch(result)) } - _ => Err(Error::failed(format!("zero_fields_of_groupd() expected a struct"))), + _ => Err(Error::failed(format!( + "zero_fields_of_groupd() expected a struct" + ))), } } -fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, - styled_name: &str, - field: &schema_capnp::field::Reader) -> ::capnp::Result { - +fn generate_setter( + gen: &GeneratorContext, + discriminant_offset: u32, + styled_name: &str, + field: &schema_capnp::field::Reader, +) -> ::capnp::Result { use crate::schema_capnp::*; let mut setter_interior = Vec::new(); @@ -775,13 +849,14 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, let discriminant_value = field.get_discriminant_value(); if discriminant_value != field::NO_DISCRIMINANT { - setter_interior.push( - Line(format!("self.builder.set_data_field::({}, {});", - discriminant_offset as usize, - discriminant_value as usize))); - let init_discrim = Line(format!("self.builder.set_data_field::({}, {});", - discriminant_offset as usize, - discriminant_value as usize)); + setter_interior.push(Line(format!( + "self.builder.set_data_field::({}, {});", + discriminant_offset as usize, discriminant_value as usize + ))); + let init_discrim = Line(format!( + "self.builder.set_data_field::({}, {});", + discriminant_offset as usize, discriminant_value as usize + )); initter_interior.push(init_discrim.clone()); initn_interior.push(init_discrim); } @@ -789,7 +864,9 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, let mut return_result = false; let mut result = Vec::new(); - let (maybe_reader_type, maybe_builder_type) : (Option, Option) = match field.which()? { + let (maybe_reader_type, maybe_builder_type): (Option, Option) = match field + .which()? + { field::Group(group) => { let params = get_params(gen, group.get_type_id())?; let params_string = if params.is_empty() { @@ -803,9 +880,14 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, initter_interior.push(zero_fields_of_group(gen, group.get_type_id())?); - initter_interior.push(Line(format!("::capnp::traits::FromStructBuilder::new(self.builder)"))); + initter_interior.push(Line(format!( + "::capnp::traits::FromStructBuilder::new(self.builder)" + ))); - (None, Some(format!("{}::Builder<'a{}>", the_mod, params_string))) + ( + None, + Some(format!("{}::Builder<'a{}>", the_mod, params_string)), + ) } field::Slot(reg_field) => { let offset = reg_field.get_offset() as usize; @@ -818,11 +900,16 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, type_::Bool(()) => { match prim_default(®_field.get_default_value()?)? { None => { - setter_interior.push(Line(format!("self.builder.set_bool_field({}, value);", offset))); + setter_interior.push(Line(format!( + "self.builder.set_bool_field({}, value);", + offset + ))); } Some(s) => { - setter_interior.push( - Line(format!("self.builder.set_bool_field_mask({}, value, {});", offset, s))); + setter_interior.push(Line(format!( + "self.builder.set_bool_field_mask({}, value, {});", + offset, s + ))); } } (Some("bool".to_string()), None) @@ -831,32 +918,49 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, let tstr = typ.type_string(gen, Leaf::Reader("'a"))?; match prim_default(®_field.get_default_value()?)? { None => { - setter_interior.push(Line(format!("self.builder.set_data_field::<{}>({}, value);", - tstr, offset))); + setter_interior.push(Line(format!( + "self.builder.set_data_field::<{}>({}, value);", + tstr, offset + ))); } Some(s) => { - setter_interior.push( - Line(format!("self.builder.set_data_field_mask::<{}>({}, value, {});", - tstr, offset, s))); + setter_interior.push(Line(format!( + "self.builder.set_data_field_mask::<{}>({}, value, {});", + tstr, offset, s + ))); } }; (Some(tstr), None) } type_::Text(()) => { - setter_interior.push(Line(format!("self.builder.get_pointer_field({}).set_text(value);", - offset))); - initter_interior.push(Line(format!("self.builder.get_pointer_field({}).init_text(size)", - offset))); + setter_interior.push(Line(format!( + "self.builder.get_pointer_field({}).set_text(value);", + offset + ))); + initter_interior.push(Line(format!( + "self.builder.get_pointer_field({}).init_text(size)", + offset + ))); initter_params.push("size: u32"); - (Some("::capnp::text::Reader<'_>".to_string()), Some("::capnp::text::Builder<'a>".to_string())) + ( + Some("::capnp::text::Reader<'_>".to_string()), + Some("::capnp::text::Builder<'a>".to_string()), + ) } type_::Data(()) => { - setter_interior.push(Line(format!("self.builder.get_pointer_field({}).set_data(value);", - offset))); - initter_interior.push(Line(format!("self.builder.get_pointer_field({}).init_data(size)", - offset))); + setter_interior.push(Line(format!( + "self.builder.get_pointer_field({}).set_data(value);", + offset + ))); + initter_interior.push(Line(format!( + "self.builder.get_pointer_field({}).init_data(size)", + offset + ))); initter_params.push("size: u32"); - (Some("::capnp::data::Reader<'_>".to_string()), Some("::capnp::data::Builder<'a>".to_string())) + ( + Some("::capnp::data::Reader<'_>".to_string()), + Some("::capnp::data::Builder<'a>".to_string()), + ) } type_::List(ot1) => { return_result = true; @@ -869,21 +973,31 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, Line(format!("::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field({}), size)", offset))); match ot1.get_element_type()?.which()? { - type_::List(_) => { - (Some(reg_field.get_type()?.type_string(gen, Leaf::Reader("'_"))?), - Some(reg_field.get_type()?.type_string(gen, Leaf::Builder("'a"))?)) - } - _ => - (Some(reg_field.get_type()?.type_string(gen, Leaf::Reader("'a"))?), - Some(reg_field.get_type()?.type_string(gen, Leaf::Builder("'a"))?)) + type_::List(_) => ( + Some(reg_field.get_type()?.type_string(gen, Leaf::Reader("'_"))?), + Some( + reg_field + .get_type()? + .type_string(gen, Leaf::Builder("'a"))?, + ), + ), + _ => ( + Some(reg_field.get_type()?.type_string(gen, Leaf::Reader("'a"))?), + Some( + reg_field + .get_type()? + .type_string(gen, Leaf::Builder("'a"))?, + ), + ), } } type_::Enum(e) => { let id = e.get_type_id(); let the_mod = gen.scope_map[&id].join("::"); - setter_interior.push( - Line(format!("self.builder.set_data_field::({}, value as u16)", - offset))); + setter_interior.push(Line(format!( + "self.builder.set_data_field::({}, value as u16)", + offset + ))); (Some(format!("{}", the_mod)), None) } type_::Struct(_) => { @@ -897,19 +1011,28 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, "<{} as ::capnp::traits::SetPointerBuilder>::set_pointer_builder(self.builder.get_pointer_field({}), value, false)", typ.type_string(gen, Leaf::Reader("'_"))?, offset))); - (Some(typ.type_string(gen, Leaf::Reader("'_"))?), - Some(typ.type_string(gen, Leaf::Builder("'a"))?)) + ( + Some(typ.type_string(gen, Leaf::Reader("'_"))?), + Some(typ.type_string(gen, Leaf::Builder("'a"))?), + ) } else { setter_interior.push( Line(format!("::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field({}), value, false)", offset))); - (Some(reg_field.get_type()?.type_string(gen, Leaf::Reader("'_"))?), - Some(reg_field.get_type()?.type_string(gen, Leaf::Builder("'a"))?)) + ( + Some(reg_field.get_type()?.type_string(gen, Leaf::Reader("'_"))?), + Some( + reg_field + .get_type()? + .type_string(gen, Leaf::Builder("'a"))?, + ), + ) } } type_::Interface(_) => { - setter_interior.push( - Line(format!("self.builder.get_pointer_field({}).set_capability(value.client.hook);", - offset))); + setter_interior.push(Line(format!( + "self.builder.get_pointer_field({}).set_capability(value.client.hook);", + offset + ))); (Some(typ.type_string(gen, Leaf::Client)?), None) } type_::AnyPointer(_) => { @@ -921,15 +1044,19 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, let builder_type = typ.type_string(gen, Leaf::Builder("'a"))?; result.push(Line("#[inline]".to_string())); - result.push(Line(format!("pub fn initn_{}(self, length: u32) -> {} {{", - styled_name, builder_type))); + result.push(Line(format!( + "pub fn initn_{}(self, length: u32) -> {} {{", + styled_name, builder_type + ))); result.push(Indent(Box::new(Branch(initn_interior)))); result.push(Indent(Box::new( Line(format!("::capnp::any_pointer::Builder::new(self.builder.get_pointer_field({})).initn_as(length)", offset))))); result.push(Line("}".to_string())); - - (Some(typ.type_string(gen, Leaf::Reader("'_"))?), Some(builder_type)) + ( + Some(typ.type_string(gen, Leaf::Reader("'_"))?), + Some(builder_type), + ) } else { initter_interior.push(Line(format!("let mut result = ::capnp::any_pointer::Builder::new(self.builder.get_pointer_field({}));", offset))); @@ -945,11 +1072,16 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, match maybe_reader_type { Some(ref reader_type) => { - let return_type = if return_result { "-> ::capnp::Result<()>" } else { "" }; + let return_type = if return_result { + "-> ::capnp::Result<()>" + } else { + "" + }; result.push(Line("#[inline]".to_string())); - result.push(Line(format!("pub fn set_{}(&mut self, {}: {}) {} {{", - styled_name, setter_param, - reader_type, return_type))); + result.push(Line(format!( + "pub fn set_{}(&mut self, {}: {}) {} {{", + styled_name, setter_param, reader_type, return_type + ))); result.push(Indent(Box::new(Branch(setter_interior)))); result.push(Line("}".to_string())); } @@ -959,8 +1091,10 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, Some(builder_type) => { result.push(Line("#[inline]".to_string())); let args = initter_params.join(", "); - result.push(Line(format!("pub fn init_{}(self, {}) -> {} {{", - styled_name, args, builder_type))); + result.push(Line(format!( + "pub fn init_{}(self, {}) -> {} {{", + styled_name, args, builder_type + ))); result.push(Indent(Box::new(Branch(initter_interior)))); result.push(Line("}".to_string())); } @@ -969,9 +1103,11 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, Ok(Branch(result)) } -fn used_params_of_group(gen: &GeneratorContext, - group_id: u64, - used_params: &mut HashSet) -> capnp::Result<()> { +fn used_params_of_group( + gen: &GeneratorContext, + group_id: u64, + used_params: &mut HashSet, +) -> capnp::Result<()> { let node = gen.node_map[&group_id]; match node.which()? { schema_capnp::node::Struct(st) => { @@ -986,56 +1122,58 @@ fn used_params_of_group(gen: &GeneratorContext, } } Ok(()) - }, - _ => Err(Error::failed("not a group".to_string())) + } + _ => Err(Error::failed("not a group".to_string())), } } -fn used_params_of_type(gen: &GeneratorContext, - ty: schema_capnp::type_::Reader, - used_params: &mut HashSet) -> capnp::Result<()> { +fn used_params_of_type( + gen: &GeneratorContext, + ty: schema_capnp::type_::Reader, + used_params: &mut HashSet, +) -> capnp::Result<()> { use schema_capnp::type_; match ty.which()? { type_::List(ls) => { let et = ls.get_element_type()?; used_params_of_type(gen, et, used_params)?; - }, + } type_::Enum(e) => { let node_id = e.get_type_id(); let brand = e.get_brand()?; used_params_of_brand(gen, node_id, brand, used_params)?; - }, + } type_::Struct(s) => { let node_id = s.get_type_id(); let brand = s.get_brand()?; used_params_of_brand(gen, node_id, brand, used_params)?; - }, + } type_::Interface(i) => { let node_id = i.get_type_id(); let brand = i.get_brand()?; used_params_of_brand(gen, node_id, brand, used_params)?; - }, - type_::AnyPointer(ap) => { - match ap.which()? { - type_::any_pointer::Parameter(def) => { - let the_struct = &gen.node_map[&def.get_scope_id()]; - let parameters = the_struct.get_parameters()?; - let parameter = parameters.get(u32::from(def.get_parameter_index())); - let parameter_name = parameter.get_name()?; - used_params.insert(parameter_name.to_string()); - } - _ => (), - } } + type_::AnyPointer(ap) => match ap.which()? { + type_::any_pointer::Parameter(def) => { + let the_struct = &gen.node_map[&def.get_scope_id()]; + let parameters = the_struct.get_parameters()?; + let parameter = parameters.get(u32::from(def.get_parameter_index())); + let parameter_name = parameter.get_name()?; + used_params.insert(parameter_name.to_string()); + } + _ => (), + }, _ => (), } Ok(()) } -fn used_params_of_brand(gen: &GeneratorContext, - node_id: u64, - brand: schema_capnp::brand::Reader, - used_params: &mut HashSet) -> capnp::Result<()> { +fn used_params_of_brand( + gen: &GeneratorContext, + node_id: u64, + brand: schema_capnp::brand::Reader, + used_params: &mut HashSet, +) -> capnp::Result<()> { use schema_capnp::brand; let scopes = brand.get_scopes()?; let mut brand_scopes = HashMap::new(); @@ -1052,27 +1190,25 @@ fn used_params_of_brand(gen: &GeneratorContext, let params = current_node.get_parameters()?; match brand_scopes.get(¤t_node_id) { None => (), - Some(scope) => { - match scope.which()? { - brand::scope::Inherit(()) => { - for param in params.iter() { - used_params.insert(param.get_name()?.to_string()); - } + Some(scope) => match scope.which()? { + brand::scope::Inherit(()) => { + for param in params.iter() { + used_params.insert(param.get_name()?.to_string()); } - brand::scope::Bind(bindings_list_opt) => { - let bindings_list = bindings_list_opt?; - assert_eq!(bindings_list.len(), params.len()); - for binding in bindings_list.iter() { - match binding.which()? { - brand::binding::Unbound(()) => (), - brand::binding::Type(t) => { - used_params_of_type(gen, t?, used_params)?; - } + } + brand::scope::Bind(bindings_list_opt) => { + let bindings_list = bindings_list_opt?; + assert_eq!(bindings_list.len(), params.len()); + for binding in bindings_list.iter() { + match binding.which()? { + brand::binding::Unbound(()) => (), + brand::binding::Type(t) => { + used_params_of_type(gen, t?, used_params)?; } } } } - } + }, } current_node_id = current_node.get_scope_id(); } @@ -1080,13 +1216,18 @@ fn used_params_of_brand(gen: &GeneratorContext, } // return (the 'Which' enum, the 'which()' accessor, typedef, default_decls) -fn generate_union(gen: &GeneratorContext, - discriminant_offset: u32, - fields: &[schema_capnp::field::Reader], - is_reader: bool, - params: &TypeParameterTexts) - -> ::capnp::Result<(FormattedText, FormattedText, FormattedText, Vec)> -{ +fn generate_union( + gen: &GeneratorContext, + discriminant_offset: u32, + fields: &[schema_capnp::field::Reader], + is_reader: bool, + params: &TypeParameterTexts, +) -> ::capnp::Result<( + FormattedText, + FormattedText, + FormattedText, + Vec, +)> { use crate::schema_capnp::*; fn new_ty_param(ty_params: &mut Vec) -> String { @@ -1103,12 +1244,11 @@ fn generate_union(gen: &GeneratorContext, let mut ty_params = Vec::new(); let mut ty_args = Vec::new(); - let mut used_params : HashSet = HashSet::new(); + let mut used_params: HashSet = HashSet::new(); let doffset = discriminant_offset as usize; for field in fields.iter() { - let dvalue = field.get_discriminant_value() as usize; let field_name = get_field_name(*field)?; @@ -1121,10 +1261,13 @@ fn generate_union(gen: &GeneratorContext, getter_interior.push(Branch(vec![ Line(format!("{} => {{", dvalue)), - Indent(Box::new(Line(format!("::core::result::Result::Ok({}(", enumerant_name.clone())))), + Indent(Box::new(Line(format!( + "::core::result::Result::Ok({}(", + enumerant_name.clone() + )))), Indent(Box::new(Indent(Box::new(get)))), Indent(Box::new(Line("))".to_string()))), - Line("}".to_string()) + Line("}".to_string()), ])); let ty1 = match field.which() { @@ -1137,77 +1280,104 @@ fn generate_union(gen: &GeneratorContext, let fty = reg_field.get_type()?; used_params_of_type(gen, fty, &mut used_params)?; match fty.which() { - Ok(type_::Text(())) | Ok(type_::Data(())) | - Ok(type_::List(_)) | Ok(type_::Struct(_)) | - Ok(type_::AnyPointer(_)) => { + Ok(type_::Text(())) + | Ok(type_::Data(())) + | Ok(type_::List(_)) + | Ok(type_::Struct(_)) + | Ok(type_::AnyPointer(_)) => { ty_args.push(ty); new_ty_param(&mut ty_params) } - Ok(type_::Interface(_)) => { - ty - } - _ => ty + Ok(type_::Interface(_)) => ty, + _ => ty, } } - _ => ty + _ => ty, }; enum_interior.push(Line(format!("{}({}),", enumerant_name, ty1))); } - let enum_name = format!("Which{}", - if !ty_params.is_empty() { format!("<{}>", ty_params.join(",")) } - else {"".to_string()} ); - + let enum_name = format!( + "Which{}", + if !ty_params.is_empty() { + format!("<{}>", ty_params.join(",")) + } else { + "".to_string() + } + ); - getter_interior.push(Line("x => ::core::result::Result::Err(::capnp::NotInSchema(x))".to_string())); + getter_interior.push(Line( + "x => ::core::result::Result::Err(::capnp::NotInSchema(x))".to_string(), + )); - interior.push( - Branch(vec!(Line(format!("pub enum {} {{", enum_name)), - Indent(Box::new(Branch(enum_interior))), - Line("}".to_string())))); + interior.push(Branch(vec![ + Line(format!("pub enum {} {{", enum_name)), + Indent(Box::new(Branch(enum_interior))), + Line("}".to_string()), + ])); let result = Branch(interior); let field_name = if is_reader { "reader" } else { "builder" }; - let concrete_type = - format!("Which{}{}", - if is_reader {"Reader"} else {"Builder"}, - if !ty_params.is_empty() { - format!("<'a,{}>", - params.expanded_list - .iter() - .filter(|s: &&String| used_params.contains(*s)) - .map(|s| s.clone()) - .collect::>().join(",")) - } else { "".to_string() }); - - let typedef = - Line(format!("pub type {} = Which{};", - concrete_type, - if !ty_args.is_empty() {format!("<{}>", - ty_args.join(","))} else {"".to_string()})); - - let getter_result = - Branch(vec!(Line("#[inline]".to_string()), - Line(format!("pub fn which(self) -> ::core::result::Result<{}, ::capnp::NotInSchema> {{", - concrete_type)), - Indent(Box::new(Branch(vec!( - Line(format!("match self.{}.get_data_field::({}) {{", field_name, doffset)), - Indent(Box::new(Branch(getter_interior))), - Line("}".to_string()))))), - Line("}".to_string()))); + let concrete_type = format!( + "Which{}{}", + if is_reader { "Reader" } else { "Builder" }, + if !ty_params.is_empty() { + format!( + "<'a,{}>", + params + .expanded_list + .iter() + .filter(|s: &&String| used_params.contains(*s)) + .map(|s| s.clone()) + .collect::>() + .join(",") + ) + } else { + "".to_string() + } + ); + + let typedef = Line(format!( + "pub type {} = Which{};", + concrete_type, + if !ty_args.is_empty() { + format!("<{}>", ty_args.join(",")) + } else { + "".to_string() + } + )); + + let getter_result = Branch(vec![ + Line("#[inline]".to_string()), + Line(format!( + "pub fn which(self) -> ::core::result::Result<{}, ::capnp::NotInSchema> {{", + concrete_type + )), + Indent(Box::new(Branch(vec![ + Line(format!( + "match self.{}.get_data_field::({}) {{", + field_name, doffset + )), + Indent(Box::new(Branch(getter_interior))), + Line("}".to_string()), + ]))), + Line("}".to_string()), + ]); // TODO set_which() for builders? Ok((result, getter_result, typedef, default_decls)) } -fn generate_haser(discriminant_offset: u32, - styled_name: &str, - field: &schema_capnp::field::Reader, - is_reader: bool) -> ::capnp::Result { +fn generate_haser( + discriminant_offset: u32, + styled_name: &str, + field: &schema_capnp::field::Reader, + is_reader: bool, +) -> ::capnp::Result { use crate::schema_capnp::*; let mut result = Vec::new(); @@ -1216,39 +1386,43 @@ fn generate_haser(discriminant_offset: u32, let discriminant_value = field.get_discriminant_value(); if discriminant_value != field::NO_DISCRIMINANT { - interior.push( - Line(format!("if self.{}.get_data_field::({}) != {} {{ return false; }}", - member, - discriminant_offset as usize, - discriminant_value as usize))); + interior.push(Line(format!( + "if self.{}.get_data_field::({}) != {} {{ return false; }}", + member, discriminant_offset as usize, discriminant_value as usize + ))); } match field.which() { - Err(_) | Ok(field::Group(_)) => {}, - Ok(field::Slot(reg_field)) => { - match reg_field.get_type()?.which()? { - type_::Text(()) | type_::Data(()) | - type_::List(_) | type_::Struct(_) | - type_::AnyPointer(_) => { - interior.push( - Line(format!("!self.{}.get_pointer_field({}).is_null()", - member, reg_field.get_offset()))); - result.push(Line("#[inline]".to_string())); - result.push( - Line(format!("pub fn has_{}(&self) -> bool {{", styled_name))); - result.push( - Indent(Box::new(Branch(interior)))); - result.push(Line("}".to_string())); - } - _ => {} + Err(_) | Ok(field::Group(_)) => {} + Ok(field::Slot(reg_field)) => match reg_field.get_type()?.which()? { + type_::Text(()) + | type_::Data(()) + | type_::List(_) + | type_::Struct(_) + | type_::AnyPointer(_) => { + interior.push(Line(format!( + "!self.{}.get_pointer_field({}).is_null()", + member, + reg_field.get_offset() + ))); + result.push(Line("#[inline]".to_string())); + result.push(Line(format!( + "pub fn has_{}(&self) -> bool {{", + styled_name + ))); + result.push(Indent(Box::new(Branch(interior)))); + result.push(Line("}".to_string())); } - } + _ => {} + }, } Ok(Branch(result)) } -fn generate_pipeline_getter(gen: &GeneratorContext, - field: schema_capnp::field::Reader) -> ::capnp::Result { +fn generate_pipeline_getter( + gen: &GeneratorContext, + field: schema_capnp::field::Reader, +) -> ::capnp::Result { use crate::schema_capnp::{field, type_}; let name = get_field_name(field)?; @@ -1263,14 +1437,19 @@ fn generate_pipeline_getter(gen: &GeneratorContext, }; let the_mod = gen.scope_map[&group.get_type_id()].join("::"); - Ok(Branch(vec!( - Line(format!("pub fn get_{}(&self) -> {}::Pipeline{} {{", - camel_to_snake_case(name), - the_mod, - params_string)), - Indent( - Box::new(Line("::capnp::capability::FromTypelessPipeline::new(self._typeless.noop())".to_string()))), - Line("}".to_string())))) + Ok(Branch(vec![ + Line(format!( + "pub fn get_{}(&self) -> {}::Pipeline{} {{", + camel_to_snake_case(name), + the_mod, + params_string + )), + Indent(Box::new(Line( + "::capnp::capability::FromTypelessPipeline::new(self._typeless.noop())" + .to_string(), + ))), + Line("}".to_string()), + ])) } field::Slot(reg_field) => { let typ = reg_field.get_type()?; @@ -1305,9 +1484,10 @@ fn generate_pipeline_getter(gen: &GeneratorContext, // We need this to work around the fact that Rust does not allow typedefs // with unused type parameters. -fn get_ty_params_of_brand(gen: &GeneratorContext, - brand: crate::schema_capnp::brand::Reader<>) -> ::capnp::Result -{ +fn get_ty_params_of_brand( + gen: &GeneratorContext, + brand: crate::schema_capnp::brand::Reader, +) -> ::capnp::Result { let mut acc = HashSet::new(); get_ty_params_of_brand_helper(gen, &mut acc, brand)?; let mut result = String::new(); @@ -1321,20 +1501,27 @@ fn get_ty_params_of_brand(gen: &GeneratorContext, Ok(result) } -fn get_ty_params_of_type_helper(gen: &GeneratorContext, - accumulator: &mut HashSet<(u64, u16)>, - typ: crate::schema_capnp::type_::Reader<>) - -> ::capnp::Result<()> -{ +fn get_ty_params_of_type_helper( + gen: &GeneratorContext, + accumulator: &mut HashSet<(u64, u16)>, + typ: crate::schema_capnp::type_::Reader, +) -> ::capnp::Result<()> { use crate::schema_capnp::type_; match typ.which()? { - type_::Void(()) | type_::Bool(()) | - type_::Int8(()) | type_::Int16(()) | - type_::Int32(()) | type_::Int64(()) | - type_::Uint8(()) | type_::Uint16(()) | - type_::Uint32(()) | type_::Uint64(()) | - type_::Float32(()) | type_::Float64(()) | - type_::Text(_) | type_::Data(_) => {} + type_::Void(()) + | type_::Bool(()) + | type_::Int8(()) + | type_::Int16(()) + | type_::Int32(()) + | type_::Int64(()) + | type_::Uint8(()) + | type_::Uint16(()) + | type_::Uint32(()) + | type_::Uint64(()) + | type_::Float32(()) + | type_::Float64(()) + | type_::Text(_) + | type_::Data(_) => {} type_::AnyPointer(p) => { match p.which()? { type_::any_pointer::Unconstrained(_) => (), @@ -1347,31 +1534,26 @@ fn get_ty_params_of_type_helper(gen: &GeneratorContext, } } type_::List(list) => { - get_ty_params_of_type_helper( - gen, accumulator, - list.get_element_type()?)? + get_ty_params_of_type_helper(gen, accumulator, list.get_element_type()?)? } type_::Enum(e) => { - get_ty_params_of_brand_helper(gen, accumulator, - e.get_brand()?)?; + get_ty_params_of_brand_helper(gen, accumulator, e.get_brand()?)?; } type_::Struct(s) => { - get_ty_params_of_brand_helper(gen, accumulator, - s.get_brand()?)?; + get_ty_params_of_brand_helper(gen, accumulator, s.get_brand()?)?; } type_::Interface(interf) => { - get_ty_params_of_brand_helper(gen, accumulator, - interf.get_brand()?)?; + get_ty_params_of_brand_helper(gen, accumulator, interf.get_brand()?)?; } } Ok(()) } -fn get_ty_params_of_brand_helper(gen: &GeneratorContext, - accumulator: &mut HashSet<(u64, u16)>, - brand: crate::schema_capnp::brand::Reader<>) - -> ::capnp::Result<()> -{ +fn get_ty_params_of_brand_helper( + gen: &GeneratorContext, + accumulator: &mut HashSet<(u64, u16)>, + brand: crate::schema_capnp::brand::Reader, +) -> ::capnp::Result<()> { for scope in brand.get_scopes()?.iter() { let scope_id = scope.get_scope_id(); match scope.which()? { @@ -1396,13 +1578,14 @@ fn get_ty_params_of_brand_helper(gen: &GeneratorContext, Ok(()) } -fn generate_node(gen: &GeneratorContext, - node_id: u64, - node_name: &str, - // Ugh. We need this to deal with the anonymous Params and Results - // structs that go with RPC methods. - parent_node_id: Option, - ) -> ::capnp::Result { +fn generate_node( + gen: &GeneratorContext, + node_id: u64, + node_name: &str, + // Ugh. We need this to deal with the anonymous Params and Results + // structs that go with RPC methods. + parent_node_id: Option, +) -> ::capnp::Result { use crate::schema_capnp::*; let mut output: Vec = Vec::new(); @@ -1425,11 +1608,19 @@ fn generate_node(gen: &GeneratorContext, let is_generic = node_reader.get_is_generic(); if is_generic { - output.push(Line(format!("pub mod {} {{ /* {} */", node_name, params.expanded_list.join(",")))); + output.push(Line(format!( + "pub mod {} {{ /* {} */", + node_name, + params.expanded_list.join(",") + ))); } else { output.push(Line(format!("pub mod {} {{", node_name))); } - let bracketed_params = if params.params == "" { "".to_string() } else { format!("<{}>", params.params) }; + let bracketed_params = if params.params == "" { + "".to_string() + } else { + format!("<{}>", params.params) + }; let mut preamble = Vec::new(); let mut builder_members = Vec::new(); @@ -1458,39 +1649,51 @@ fn generate_node(gen: &GeneratorContext, if let Some(default) = default_decl { private_mod_interior.push(default.clone()); } - reader_members.push( - Branch(vec!( - Line("#[inline]".to_string()), - Line(format!("pub fn get_{}(self) {} {{", styled_name, ty)), - Indent(Box::new(get)), - Line("}".to_string())))); + reader_members.push(Branch(vec![ + Line("#[inline]".to_string()), + Line(format!("pub fn get_{}(self) {} {{", styled_name, ty)), + Indent(Box::new(get)), + Line("}".to_string()), + ])); let (ty_b, get_b, _) = getter_text(gen, &field, false, true)?; - builder_members.push( - Branch(vec!( - Line("#[inline]".to_string()), - Line(format!("pub fn get_{}(self) {} {{", styled_name, ty_b)), - Indent(Box::new(get_b)), - Line("}".to_string())))); - + builder_members.push(Branch(vec![ + Line("#[inline]".to_string()), + Line(format!("pub fn get_{}(self) {} {{", styled_name, ty_b)), + Indent(Box::new(get_b)), + Line("}".to_string()), + ])); } else { union_fields.push(field); } - builder_members.push(generate_setter(gen, discriminant_offset, - &styled_name, &field)?); - - reader_members.push(generate_haser(discriminant_offset, &styled_name, &field, true)?); - builder_members.push(generate_haser(discriminant_offset, &styled_name, &field, false)?); + builder_members.push(generate_setter( + gen, + discriminant_offset, + &styled_name, + &field, + )?); + + reader_members.push(generate_haser( + discriminant_offset, + &styled_name, + &field, + true, + )?); + builder_members.push(generate_haser( + discriminant_offset, + &styled_name, + &field, + false, + )?); match field.which() { Ok(field::Group(group)) => { let id = group.get_type_id(); - let text = generate_node(gen, id, - gen.get_last_name(id)?, None)?; + let text = generate_node(gen, id, gen.get_last_name(id)?, None)?; nested_output.push(text); } - _ => { } + _ => {} } } @@ -1511,7 +1714,7 @@ fn generate_node(gen: &GeneratorContext, let mut reexports = String::new(); reexports.push_str("pub use self::Which::{"); let mut whichs = Vec::new(); - for f in union_fields.iter(){ + for f in union_fields.iter() { whichs.push(capitalize_first_letter(get_field_name(*f)?)); } reexports.push_str(&whichs.join(",")); @@ -1528,10 +1731,10 @@ fn generate_node(gen: &GeneratorContext, format!("const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize {{ data: {}, pointers: {} }};", data_size as usize, pointer_size as usize)))), Line("}".to_string()))); - private_mod_interior.push( - Line( - format!("pub const TYPE_ID: u64 = {};", format_u64(node_id)))); - + private_mod_interior.push(Line(format!( + "pub const TYPE_ID: u64 = {};", + format_u64(node_id) + ))); let from_pointer_builder_impl = Branch(vec![ @@ -1737,9 +1940,11 @@ fn generate_node(gen: &GeneratorContext, Line("}".to_string()), ]; - output.push(Indent(Box::new(Branch(vec!(Branch(accessors), - Branch(which_enums), - Branch(nested_output)))))); + output.push(Indent(Box::new(Branch(vec![ + Branch(accessors), + Branch(which_enums), + Branch(nested_output), + ])))); output.push(Line("}".to_string())); } @@ -1753,17 +1958,22 @@ fn generate_node(gen: &GeneratorContext, for (ii, enumerant) in enumerants.into_iter().enumerate() { let enumerant = capitalize_first_letter(get_enumerant_name(enumerant)?); members.push(Line(format!("{} = {},", enumerant, ii))); - match_branches.push( - Line(format!("{} => ::core::result::Result::Ok({}::{}),", ii, last_name, enumerant))); + match_branches.push(Line(format!( + "{} => ::core::result::Result::Ok({}::{}),", + ii, last_name, enumerant + ))); } - match_branches.push(Line("n => ::core::result::Result::Err(::capnp::NotInSchema(n)),".to_string())); + match_branches.push(Line( + "n => ::core::result::Result::Err(::capnp::NotInSchema(n)),".to_string(), + )); - output.push(Branch(vec!( + output.push(Branch(vec![ Line("#[repr(u16)]".to_string()), Line("#[derive(Clone, Copy, Debug, PartialEq, Eq)]".to_string()), Line(format!("pub enum {} {{", last_name)), Indent(Box::new(Branch(members))), - Line("}".to_string())))); + Line("}".to_string()), + ])); output.push( Branch(vec!( @@ -1788,11 +1998,16 @@ fn generate_node(gen: &GeneratorContext, Box::new(Line("fn to_u16(self) -> u16 { self as u16 }".to_string()))), Line("}".to_string())))); - output.push( - Branch(vec!( - Line(format!("impl ::capnp::traits::HasTypeId for {} {{", last_name)), - Indent(Box::new(Line(format!("const TYPE_ID: u64 = {}u64;", format_u64(node_id)).to_string()))), - Line("}".to_string())))); + output.push(Branch(vec![ + Line(format!( + "impl ::capnp::traits::HasTypeId for {} {{", + last_name + )), + Indent(Box::new(Line( + format!("const TYPE_ID: u64 = {}u64;", format_u64(node_id)).to_string(), + ))), + Line("}".to_string()), + ])); } node::Interface(interface) => { @@ -1808,11 +2023,18 @@ fn generate_node(gen: &GeneratorContext, let mut dispatch_arms = Vec::new(); let mut private_mod_interior = Vec::new(); - let bracketed_params = if params.params == "" { "".to_string() } else { format!("<{}>", params.params) }; + let bracketed_params = if params.params == "" { + "".to_string() + } else { + format!("<{}>", params.params) + }; - private_mod_interior.push(Line(format!("pub const TYPE_ID: u64 = {};", format_u64(node_id)))); + private_mod_interior.push(Line(format!( + "pub const TYPE_ID: u64 = {};", + format_u64(node_id) + ))); - mod_interior.push(Line ("#![allow(unused_variables)]".to_string())); + mod_interior.push(Line("#![allow(unused_variables)]".to_string())); let methods = interface.get_methods()?; for (ordinal, method) in methods.into_iter().enumerate() { @@ -1828,11 +2050,19 @@ fn generate_node(gen: &GeneratorContext, names.push(local_name); (names, params.params.clone()) } else { - (gen.scope_map[¶m_node.get_id()].clone(), - get_ty_params_of_brand(gen, method.get_param_brand()?)?) + ( + gen.scope_map[¶m_node.get_id()].clone(), + get_ty_params_of_brand(gen, method.get_param_brand()?)?, + ) }; - let param_type = do_branding(gen, param_id, method.get_param_brand()?, - Leaf::Owned, param_scopes.join("::"), Some(node_id))?; + let param_type = do_branding( + gen, + param_id, + method.get_param_brand()?, + Leaf::Owned, + param_scopes.join("::"), + Some(node_id), + )?; let result_id = method.get_result_struct_type(); let result_node = &gen.node_map[&result_id]; @@ -1843,24 +2073,36 @@ fn generate_node(gen: &GeneratorContext, names.push(local_name); (names, params.params.clone()) } else { - (gen.scope_map[&result_node.get_id()].clone(), - get_ty_params_of_brand(gen, method.get_result_brand()?)?) + ( + gen.scope_map[&result_node.get_id()].clone(), + get_ty_params_of_brand(gen, method.get_result_brand()?)?, + ) }; - let result_type = do_branding(gen, result_id, method.get_result_brand()?, - Leaf::Owned, result_scopes.join("::"), Some(node_id))?; + let result_type = do_branding( + gen, + result_id, + method.get_result_brand()?, + Leaf::Owned, + result_scopes.join("::"), + Some(node_id), + )?; dispatch_arms.push( Line(format!( "{} => server.{}(::capnp::private::capability::internal_get_typed_params(params), ::capnp::private::capability::internal_get_typed_results(results)),", ordinal, module_name(name)))); - mod_interior.push( - Line(format!( - "pub type {}Params<{}> = ::capnp::capability::Params<{}>;", - capitalize_first_letter(name), params_ty_params, param_type))); - mod_interior.push( - Line(format!( - "pub type {}Results<{}> = ::capnp::capability::Results<{}>;", - capitalize_first_letter(name), results_ty_params, result_type))); + mod_interior.push(Line(format!( + "pub type {}Params<{}> = ::capnp::capability::Params<{}>;", + capitalize_first_letter(name), + params_ty_params, + param_type + ))); + mod_interior.push(Line(format!( + "pub type {}Results<{}> = ::capnp::capability::Results<{}>;", + capitalize_first_letter(name), + results_ty_params, + result_type + ))); server_interior.push( Line(format!( "fn {}(&mut self, _: {}Params<{}>, _: {}Results<{}>) -> ::capnp::capability::Promise<(), ::capnp::Error> {{ ::capnp::capability::Promise::err(::capnp::Error::unimplemented(\"method {}::Server::{} not implemented\".to_string())) }}", @@ -1870,12 +2112,17 @@ fn generate_node(gen: &GeneratorContext, node_name, module_name(name), ))); - client_impl_interior.push( - Line(format!("pub fn {}_request(&self) -> ::capnp::capability::Request<{},{}> {{", - camel_to_snake_case(name), param_type, result_type))); - - client_impl_interior.push(Indent( - Box::new(Line(format!("self.client.new_call(_private::TYPE_ID, {}, None)", ordinal))))); + client_impl_interior.push(Line(format!( + "pub fn {}_request(&self) -> ::capnp::capability::Request<{},{}> {{", + camel_to_snake_case(name), + param_type, + result_type + ))); + + client_impl_interior.push(Indent(Box::new(Line(format!( + "self.client.new_call(_private::TYPE_ID, {}, None)", + ordinal + ))))); client_impl_interior.push(Line("}".to_string())); method.get_annotations()?; @@ -1887,14 +2134,16 @@ fn generate_node(gen: &GeneratorContext, let mut base_traits = Vec::new(); fn find_super_interfaces<'a>( - interface: crate::schema_capnp::node::interface::Reader<'a>, - all_extends: &mut Vec<::Reader<'a>>, - gen: &GeneratorContext<'a> - ) -> ::capnp::Result<()>{ + interface: crate::schema_capnp::node::interface::Reader<'a>, + all_extends: &mut Vec<::Reader<'a>>, + gen: &GeneratorContext<'a>, + ) -> ::capnp::Result<()> { let extends = interface.get_superclasses()?; for superclass in extends { - if let node::Interface(interface) = gen.node_map[&superclass.get_id()].which()? { - find_super_interfaces(interface, all_extends, gen)?; + if let node::Interface(interface) = + gen.node_map[&superclass.get_id()].which()? + { + find_super_interfaces(interface, all_extends, gen)?; } all_extends.push(superclass); } @@ -1913,16 +2162,27 @@ fn generate_node(gen: &GeneratorContext, type_id, do_branding( gen, type_id, brand, Leaf::ServerDispatch, the_mod.clone(), None)?))); - base_traits.push( - do_branding(gen, type_id, brand, Leaf::Server, the_mod, None)?); + base_traits.push(do_branding( + gen, + type_id, + brand, + Leaf::Server, + the_mod, + None, + )?); + } + if !extends.is_empty() { + format!(": {}", base_traits.join(" + ")) + } else { + "".to_string() } - if !extends.is_empty() { format!(": {}", base_traits.join(" + ")) } - else { "".to_string() } }; mod_interior.push(BlankLine); mod_interior.push(Line(format!("pub struct Client{} {{", bracketed_params))); - mod_interior.push(Indent(Box::new(Line("pub client: ::capnp::capability::Client,".to_string())))); + mod_interior.push(Indent(Box::new(Line( + "pub client: ::capnp::capability::Client,".to_string(), + )))); if is_generic { mod_interior.push(Indent(Box::new(Line(params.phantom_data_type.clone())))); } @@ -2002,12 +2262,16 @@ fn generate_node(gen: &GeneratorContext, Line("}".to_string())]))), Line("}".to_string())])); - mod_interior.push( - Branch(vec!( - Line(format!("impl {0} ::capnp::traits::HasTypeId for Client{0} {{", - bracketed_params)), - Indent(Box::new(Line("const TYPE_ID: u64 = _private::TYPE_ID;".to_string()))), - Line("}".to_string())))); + mod_interior.push(Branch(vec![ + Line(format!( + "impl {0} ::capnp::traits::HasTypeId for Client{0} {{", + bracketed_params + )), + Indent(Box::new(Line( + "const TYPE_ID: u64 = _private::TYPE_ID;".to_string(), + ))), + Line("}".to_string()), + ])); mod_interior.push( Branch(vec!( @@ -2017,20 +2281,34 @@ fn generate_node(gen: &GeneratorContext, Indent(Box::new(Line("}".to_string()))), Line("}".to_string())))); - mod_interior.push( - Branch(vec!(Line(format!("impl {0} Client{0} {{", bracketed_params)), - Indent(Box::new(Branch(client_impl_interior))), - Line("}".to_string())))); + mod_interior.push(Branch(vec![ + Line(format!("impl {0} Client{0} {{", bracketed_params)), + Indent(Box::new(Branch(client_impl_interior))), + Line("}".to_string()), + ])); - mod_interior.push(Branch(vec!(Line(format!("pub trait Server<{}> {} {} {{", params.params, server_base, params.where_clause)), - Indent(Box::new(Branch(server_interior))), - Line("}".to_string())))); + mod_interior.push(Branch(vec![ + Line(format!( + "pub trait Server<{}> {} {} {{", + params.params, server_base, params.where_clause + )), + Indent(Box::new(Branch(server_interior))), + Line("}".to_string()), + ])); - mod_interior.push(Branch(vec!(Line(format!("pub struct ServerDispatch<_T,{}> {{", params.params)), - Indent(Box::new(Line("pub server: _T,".to_string()))), - Indent(Box::new(Branch(if is_generic { - vec!(Line(params.phantom_data_type.clone())) } else { vec!() } ))), - Line("}".to_string())))); + mod_interior.push(Branch(vec![ + Line(format!( + "pub struct ServerDispatch<_T,{}> {{", + params.params + )), + Indent(Box::new(Line("pub server: _T,".to_string()))), + Indent(Box::new(Branch(if is_generic { + vec![Line(params.phantom_data_type.clone())] + } else { + vec![] + }))), + Line("}".to_string()), + ])); mod_interior.push(Branch(vec![ Line( @@ -2100,18 +2378,21 @@ fn generate_node(gen: &GeneratorContext, Indent(Box::new(Line("}".to_string()))), Line("}".to_string())))); - mod_interior.push( - Branch(vec!( - Line("pub mod _private {".to_string()), - Indent(Box::new(Branch(private_mod_interior))), - Line("}".to_string()), - ))); + mod_interior.push(Branch(vec![ + Line("pub mod _private {".to_string()), + Indent(Box::new(Branch(private_mod_interior))), + Line("}".to_string()), + ])); - mod_interior.push(Branch(vec!(Branch(nested_output)))); + mod_interior.push(Branch(vec![Branch(nested_output)])); output.push(BlankLine); if is_generic { - output.push(Line(format!("pub mod {} {{ /* ({}) */", node_name, params.expanded_list.join(",")))); + output.push(Line(format!( + "pub mod {} {{ /* ({}) */", + node_name, + params.expanded_list.join(",") + ))); } else { output.push(Line(format!("pub mod {} {{", node_name))); } @@ -2124,22 +2405,44 @@ fn generate_node(gen: &GeneratorContext, let typ = c.get_type()?; let formatted_text = match (typ.which()?, c.get_value()?.which()?) { - (type_::Void(()), value::Void(())) => Line(format!("pub const {}: () = ();", styled_name)), - (type_::Bool(()), value::Bool(b)) => Line(format!("pub const {}: bool = {};", styled_name, b)), - (type_::Int8(()), value::Int8(i)) => Line(format!("pub const {}: i8 = {};", styled_name, i)), - (type_::Int16(()), value::Int16(i)) => Line(format!("pub const {}: i16 = {};", styled_name, i)), - (type_::Int32(()), value::Int32(i)) => Line(format!("pub const {}: i32 = {};", styled_name, i)), - (type_::Int64(()), value::Int64(i)) => Line(format!("pub const {}: i64 = {};", styled_name, i)), - (type_::Uint8(()), value::Uint8(i)) => Line(format!("pub const {}: u8 = {};", styled_name, i)), - (type_::Uint16(()), value::Uint16(i)) => Line(format!("pub const {}: u16 = {};", styled_name, i)), - (type_::Uint32(()), value::Uint32(i)) => Line(format!("pub const {}: u32 = {};", styled_name, i)), - (type_::Uint64(()), value::Uint64(i)) => Line(format!("pub const {}: u64 = {};", styled_name, i)), + (type_::Void(()), value::Void(())) => { + Line(format!("pub const {}: () = ();", styled_name)) + } + (type_::Bool(()), value::Bool(b)) => { + Line(format!("pub const {}: bool = {};", styled_name, b)) + } + (type_::Int8(()), value::Int8(i)) => { + Line(format!("pub const {}: i8 = {};", styled_name, i)) + } + (type_::Int16(()), value::Int16(i)) => { + Line(format!("pub const {}: i16 = {};", styled_name, i)) + } + (type_::Int32(()), value::Int32(i)) => { + Line(format!("pub const {}: i32 = {};", styled_name, i)) + } + (type_::Int64(()), value::Int64(i)) => { + Line(format!("pub const {}: i64 = {};", styled_name, i)) + } + (type_::Uint8(()), value::Uint8(i)) => { + Line(format!("pub const {}: u8 = {};", styled_name, i)) + } + (type_::Uint16(()), value::Uint16(i)) => { + Line(format!("pub const {}: u16 = {};", styled_name, i)) + } + (type_::Uint32(()), value::Uint32(i)) => { + Line(format!("pub const {}: u32 = {};", styled_name, i)) + } + (type_::Uint64(()), value::Uint64(i)) => { + Line(format!("pub const {}: u64 = {};", styled_name, i)) + } - (type_::Float32(()), value::Float32(f)) => - Line(format!("pub const {}: f32 = {:e}f32;", styled_name, f)), + (type_::Float32(()), value::Float32(f)) => { + Line(format!("pub const {}: f32 = {:e}f32;", styled_name, f)) + } - (type_::Float64(()), value::Float64(f)) => - Line(format!("pub const {}: f64 = {:e}f64;", styled_name, f)), + (type_::Float64(()), value::Float64(f)) => { + Line(format!("pub const {}: f64 = {:e}f64;", styled_name, f)) + } (type_::Enum(e), value::Enum(v)) => { if let Some(node) = gen.node_map.get(&e.get_type_id()) { @@ -2150,31 +2453,47 @@ fn generate_node(gen: &GeneratorContext, let variant = capitalize_first_letter(get_enumerant_name(enumerant)?); let type_string = typ.type_string(gen, Leaf::Owned)?; - Line(format!("pub const {}: {} = {}::{};", - styled_name, - &type_string, - &type_string, - variant)) + Line(format!( + "pub const {}: {} = {}::{};", + styled_name, &type_string, &type_string, variant + )) } else { - return Err(Error::failed(format!("enumerant out of range: {}", v))); + return Err(Error::failed(format!( + "enumerant out of range: {}", + v + ))); } } _ => { - return Err(Error::failed(format!("bad enum type ID: {}", e.get_type_id()))); + return Err(Error::failed(format!( + "bad enum type ID: {}", + e.get_type_id() + ))); } } } else { - return Err(Error::failed(format!("bad enum type ID: {}", e.get_type_id()))); + return Err(Error::failed(format!( + "bad enum type ID: {}", + e.get_type_id() + ))); } } - (type_::Text(()), value::Text(t)) => - Line(format!("pub const {}: &'static str = {:?};", styled_name, t?)), - (type_::Data(()), value::Data(d)) => - Line(format!("pub const {}: &'static [u8] = &{:?};", styled_name, d?)), - - (type_::List(_), value::List(v)) => generate_pointer_constant(gen, &styled_name, typ, v)?, - (type_::Struct(_), value::Struct(v)) => generate_pointer_constant(gen, &styled_name, typ, v)?, + (type_::Text(()), value::Text(t)) => Line(format!( + "pub const {}: &'static str = {:?};", + styled_name, t? + )), + (type_::Data(()), value::Data(d)) => Line(format!( + "pub const {}: &'static [u8] = &{:?};", + styled_name, d? + )), + + (type_::List(_), value::List(v)) => { + generate_pointer_constant(gen, &styled_name, typ, v)? + } + (type_::Struct(_), value::Struct(v)) => { + generate_pointer_constant(gen, &styled_name, typ, v)? + } (type_::Interface(_t), value::Interface(())) => { return Err(Error::unimplemented(format!("interface constants"))); @@ -2183,13 +2502,15 @@ fn generate_node(gen: &GeneratorContext, return Err(Error::unimplemented(format!("anypointer constants"))); } - _ => { return Err(Error::failed(format!("type does not match value"))); } + _ => { + return Err(Error::failed(format!("type does not match value"))); + } }; output.push(formatted_text); } - node::Annotation( _annotation_reader ) => (), + node::Annotation(_annotation_reader) => (), } Ok(Branch(output)) @@ -2197,11 +2518,17 @@ fn generate_node(gen: &GeneratorContext, // The capnp crate defines a blanket impl of capnp::Read for R where R: std::io::Read, // but we can't use that here because it lives behind the "std" feature flag. -struct ReadWrapper where R: std::io::Read { +struct ReadWrapper +where + R: std::io::Read, +{ inner: R, } -impl capnp::io::Read for ReadWrapper where R: std::io::Read { +impl capnp::io::Read for ReadWrapper +where + R: std::io::Read, +{ fn read(&mut self, buf: &mut [u8]) -> capnp::Result { loop { match std::io::Read::read(&mut self.inner, buf) { @@ -2215,11 +2542,17 @@ impl capnp::io::Read for ReadWrapper where R: std::io::Read { // The capnp crate defines a blanket impl of capnp::Write for R where R: std::io::Write, // but we can't use that here because it lives behind the "std" feature flag. -struct WriteWrapper where W: std::io::Write { +struct WriteWrapper +where + W: std::io::Write, +{ inner: W, } -impl capnp::io::Write for WriteWrapper where W: std::io::Write { +impl capnp::io::Write for WriteWrapper +where + W: std::io::Write, +{ fn write_all(&mut self, buf: &[u8]) -> ::capnp::Result<()> { std::io::Write::write_all(&mut self.inner, buf).map_err(convert_io_err)?; Ok(()) diff --git a/capnpc/src/codegen_types.rs b/capnpc/src/codegen_types.rs index 00c01e0c7..174f82e47 100644 --- a/capnpc/src/codegen_types.rs +++ b/capnpc/src/codegen_types.rs @@ -19,13 +19,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +use crate::codegen; +use crate::codegen::GeneratorContext; use crate::schema_capnp::{brand, node, type_}; use capnp::Error; -use crate::codegen; -use crate::codegen::{GeneratorContext}; use std::collections::hash_map::HashMap; -#[derive(Copy,Clone,PartialEq)] +#[derive(Copy, Clone, PartialEq)] pub enum Leaf { Reader(&'static str), Builder(&'static str), @@ -33,11 +33,11 @@ pub enum Leaf { Client, Server, ServerDispatch, - Pipeline + Pipeline, } impl ::std::fmt::Display for Leaf { - fn fmt(&self, fmt:&mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { let display_string = match self { &Leaf::Reader(lt) => format!("Reader<{}>", lt), &Leaf::Builder(lt) => format!("Builder<{}>", lt), @@ -67,7 +67,11 @@ impl Leaf { fn _have_lifetime(&self) -> bool { match self { &Leaf::Reader(_) | &Leaf::Builder(_) => true, - &Leaf::Owned | &Leaf::Client | &Leaf::Server | &Leaf::ServerDispatch | &Leaf::Pipeline => false, + &Leaf::Owned + | &Leaf::Client + | &Leaf::Server + | &Leaf::ServerDispatch + | &Leaf::Pipeline => false, } } } @@ -84,33 +88,48 @@ pub struct TypeParameterTexts { // this is a collection of helpers acting on a "Node" (most of them are Type definitions) pub trait RustNodeInfo { - fn parameters_texts(&self, gen: &crate::codegen::GeneratorContext, - parent_node_id: Option) -> TypeParameterTexts; + fn parameters_texts( + &self, + gen: &crate::codegen::GeneratorContext, + parent_node_id: Option, + ) -> TypeParameterTexts; } // this is a collection of helpers acting on a "Type" (someplace where a Type is used, not defined) pub trait RustTypeInfo { - fn is_prim(&self) -> Result; fn is_parameter(&self) -> Result; fn is_branded(&self) -> Result; - fn type_string(&self, gen:&codegen::GeneratorContext, module:Leaf) -> Result; + fn type_string(&self, gen: &codegen::GeneratorContext, module: Leaf) -> Result; } -impl <'a> RustNodeInfo for node::Reader<'a> { - fn parameters_texts(&self, gen:&crate::codegen::GeneratorContext, - parent_node_id: Option) -> TypeParameterTexts { +impl<'a> RustNodeInfo for node::Reader<'a> { + fn parameters_texts( + &self, + gen: &crate::codegen::GeneratorContext, + parent_node_id: Option, + ) -> TypeParameterTexts { if self.get_is_generic() { let params = get_type_parameters(gen, self.get_id(), parent_node_id); - let type_parameters = params.iter().map(|param| { - format!("{}",param) - }).collect::>().join(","); - let where_clause = "where ".to_string() + &*(params.iter().map(|param| { - format!("{}: ::capnp::traits::Owned", param) - }).collect::>().join(", ") + " "); - let where_clause_with_static = "where ".to_string() + &*(params.iter().map(|param| { - format!("{}:'static + ::capnp::traits::Owned", param) - }).collect::>().join(", ") + " "); + let type_parameters = params + .iter() + .map(|param| format!("{}", param)) + .collect::>() + .join(","); + let where_clause = "where ".to_string() + + &*(params + .iter() + .map(|param| format!("{}: ::capnp::traits::Owned", param)) + .collect::>() + .join(", ") + + " "); + let where_clause_with_static = "where ".to_string() + + &*(params + .iter() + .map(|param| format!("{}:'static + ::capnp::traits::Owned", param)) + .collect::>() + .join(", ") + + " "); let pipeline_where_clause = "where ".to_string() + &*(params.iter().map(|param| { format!("{}: ::capnp::traits::Pipelined, <{} as ::capnp::traits::Pipelined>::Pipeline: ::capnp::capability::FromTypelessPipeline", param, param) }).collect::>().join(", ") + " "); @@ -118,7 +137,10 @@ impl <'a> RustNodeInfo for node::Reader<'a> { // omit parens to avoid linter error format!("_phantom: ::core::marker::PhantomData<{}>", type_parameters) } else { - format!("_phantom: ::core::marker::PhantomData<({})>", type_parameters) + format!( + "_phantom: ::core::marker::PhantomData<({})>", + type_parameters + ) }; let phantom_data_value = "_phantom: ::core::marker::PhantomData,".to_string(); @@ -129,11 +151,11 @@ impl <'a> RustNodeInfo for node::Reader<'a> { where_clause_with_static, pipeline_where_clause, phantom_data_type, - phantom_data_value + phantom_data_value, } } else { TypeParameterTexts { - expanded_list: vec!(), + expanded_list: vec![], params: "".to_string(), where_clause: "".to_string(), where_clause_with_static: "".to_string(), @@ -145,17 +167,21 @@ impl <'a> RustNodeInfo for node::Reader<'a> { } } -impl <'a> RustTypeInfo for type_::Reader<'a> { - - fn type_string(&self, gen:&codegen::GeneratorContext, module:Leaf) -> Result { - +impl<'a> RustTypeInfo for type_::Reader<'a> { + fn type_string( + &self, + gen: &codegen::GeneratorContext, + module: Leaf, + ) -> Result { let local_lifetime = match module { Leaf::Reader(lt) => lt, Leaf::Builder(lt) => lt, _ => "", }; - let lifetime_comma = if local_lifetime == "" { "".to_string() } else { + let lifetime_comma = if local_lifetime == "" { + "".to_string() + } else { format!("{},", local_lifetime) }; @@ -174,102 +200,126 @@ impl <'a> RustTypeInfo for type_::Reader<'a> { type_::Float64(()) => Ok("f64".to_string()), type_::Text(()) => Ok(format!("::capnp::text::{}", module)), type_::Data(()) => Ok(format!("::capnp::data::{}", module)), - type_::Struct(st) => { - do_branding(gen, st.get_type_id(), st.get_brand()?, module, - gen.scope_map[&st.get_type_id()].join("::"), None) - } - type_::Interface(interface) => { - do_branding(gen, interface.get_type_id(), interface.get_brand()?, module, - gen.scope_map[&interface.get_type_id()].join("::"), None) - } + type_::Struct(st) => do_branding( + gen, + st.get_type_id(), + st.get_brand()?, + module, + gen.scope_map[&st.get_type_id()].join("::"), + None, + ), + type_::Interface(interface) => do_branding( + gen, + interface.get_type_id(), + interface.get_brand()?, + module, + gen.scope_map[&interface.get_type_id()].join("::"), + None, + ), type_::List(ot1) => { let element_type = ot1.get_element_type()?; match element_type.which()? { type_::Struct(_) => { let inner = element_type.type_string(gen, Leaf::Owned)?; - Ok(format!("::capnp::struct_list::{}<{}{}>", module.bare_name(), lifetime_comma, inner)) - }, + Ok(format!( + "::capnp::struct_list::{}<{}{}>", + module.bare_name(), + lifetime_comma, + inner + )) + } type_::Enum(_) => { let inner = element_type.type_string(gen, Leaf::Owned)?; - Ok(format!("::capnp::enum_list::{}<{}{}>", module.bare_name(), lifetime_comma, inner)) - }, + Ok(format!( + "::capnp::enum_list::{}<{}{}>", + module.bare_name(), + lifetime_comma, + inner + )) + } type_::List(_) => { let inner = element_type.type_string(gen, Leaf::Owned)?; - Ok(format!("::capnp::list_list::{}<{}{}>", module.bare_name(), lifetime_comma, inner)) - }, - type_::Text(()) => { - Ok(format!("::capnp::text_list::{}", module)) - }, - type_::Data(()) => { - Ok(format!("::capnp::data_list::{}", module)) - }, + Ok(format!( + "::capnp::list_list::{}<{}{}>", + module.bare_name(), + lifetime_comma, + inner + )) + } + type_::Text(()) => Ok(format!("::capnp::text_list::{}", module)), + type_::Data(()) => Ok(format!("::capnp::data_list::{}", module)), type_::Interface(_) => { let inner = element_type.type_string(gen, Leaf::Client)?; - Ok(format!("::capnp::capability_list::{}<{}{}>", module.bare_name(), lifetime_comma, inner)) + Ok(format!( + "::capnp::capability_list::{}<{}{}>", + module.bare_name(), + lifetime_comma, + inner + )) + } + type_::AnyPointer(_) => { + Err(Error::failed("List(AnyPointer) is unsupported".to_string())) } - type_::AnyPointer(_) => Err(Error::failed("List(AnyPointer) is unsupported".to_string())), _ => { let inner = element_type.type_string(gen, Leaf::Owned)?; - Ok(format!("::capnp::primitive_list::{}<{}{}>", module.bare_name(), lifetime_comma, inner)) - }, + Ok(format!( + "::capnp::primitive_list::{}<{}{}>", + module.bare_name(), + lifetime_comma, + inner + )) + } } - }, + } type_::Enum(en) => { let scope = &gen.scope_map[&en.get_type_id()]; Ok(scope.join("::").to_string()) - }, - type_::AnyPointer(pointer) => { - match pointer.which()? { - type_::any_pointer::Parameter(def) => { - let the_struct = &gen.node_map[&def.get_scope_id()]; - let parameters = the_struct.get_parameters()?; - let parameter = parameters.get(u32::from(def.get_parameter_index())); - let parameter_name = parameter.get_name()?; - match module { - Leaf::Owned => Ok(parameter_name.to_string()), - Leaf::Reader(lifetime) => { - Ok(format!( - "<{} as ::capnp::traits::Owned>::Reader<{}>", - parameter_name, lifetime)) - } - Leaf::Builder(lifetime) => { - Ok(format!( - "<{} as ::capnp::traits::Owned>::Builder<{}>", - parameter_name, lifetime)) - } - Leaf::Pipeline => { - Ok(format!("<{} as ::capnp::traits::Pipelined>::Pipeline", parameter_name)) - } - _ => Err(Error::unimplemented("unimplemented any_pointer leaf".to_string())), - } - }, - _ => { - match module { - Leaf::Reader(lifetime) => { - Ok(format!("::capnp::any_pointer::Reader<{}>", lifetime)) - } - Leaf::Builder(lifetime) => { - Ok(format!("::capnp::any_pointer::Builder<{}>", lifetime)) - } - _ => { - Ok(format!("::capnp::any_pointer::{}", module)) - } - } + } + type_::AnyPointer(pointer) => match pointer.which()? { + type_::any_pointer::Parameter(def) => { + let the_struct = &gen.node_map[&def.get_scope_id()]; + let parameters = the_struct.get_parameters()?; + let parameter = parameters.get(u32::from(def.get_parameter_index())); + let parameter_name = parameter.get_name()?; + match module { + Leaf::Owned => Ok(parameter_name.to_string()), + Leaf::Reader(lifetime) => Ok(format!( + "<{} as ::capnp::traits::Owned>::Reader<{}>", + parameter_name, lifetime + )), + Leaf::Builder(lifetime) => Ok(format!( + "<{} as ::capnp::traits::Owned>::Builder<{}>", + parameter_name, lifetime + )), + Leaf::Pipeline => Ok(format!( + "<{} as ::capnp::traits::Pipelined>::Pipeline", + parameter_name + )), + _ => Err(Error::unimplemented( + "unimplemented any_pointer leaf".to_string(), + )), } } - } + _ => match module { + Leaf::Reader(lifetime) => { + Ok(format!("::capnp::any_pointer::Reader<{}>", lifetime)) + } + Leaf::Builder(lifetime) => { + Ok(format!("::capnp::any_pointer::Builder<{}>", lifetime)) + } + _ => Ok(format!("::capnp::any_pointer::{}", module)), + }, + }, } } fn is_parameter(&self) -> Result { match self.which()? { - type_::AnyPointer(pointer) => { - match pointer.which()? { - type_::any_pointer::Parameter(_) => Ok(true), - _ => Ok(false), - } - } - _ => Ok(false) + type_::AnyPointer(pointer) => match pointer.which()? { + type_::any_pointer::Parameter(_) => Ok(true), + _ => Ok(false), + }, + _ => Ok(false), } } @@ -280,29 +330,40 @@ impl <'a> RustTypeInfo for type_::Reader<'a> { let scopes = brand.get_scopes()?; Ok(scopes.len() > 0) } - _ => Ok(false) + _ => Ok(false), } } #[inline(always)] fn is_prim(&self) -> Result { match self.which()? { - type_::Int8(()) | type_::Int16(()) | type_::Int32(()) | type_::Int64(()) | - type_::Uint8(()) | type_::Uint16(()) | type_::Uint32(()) | type_::Uint64(()) | - type_::Float32(()) | type_::Float64(()) | type_::Void(()) | type_::Bool(()) => Ok(true), - _ => Ok(false) + type_::Int8(()) + | type_::Int16(()) + | type_::Int32(()) + | type_::Int64(()) + | type_::Uint8(()) + | type_::Uint16(()) + | type_::Uint32(()) + | type_::Uint64(()) + | type_::Float32(()) + | type_::Float64(()) + | type_::Void(()) + | type_::Bool(()) => Ok(true), + _ => Ok(false), } } } /// /// -pub fn do_branding(gen: &GeneratorContext, - node_id: u64, - brand: brand::Reader, - leaf: Leaf, - the_mod: String, - mut parent_scope_id: Option) -> Result { +pub fn do_branding( + gen: &GeneratorContext, + node_id: u64, + brand: brand::Reader, + leaf: Leaf, + the_mod: String, + mut parent_scope_id: Option, +) -> Result { let scopes = brand.get_scopes()?; let mut brand_scopes = HashMap::new(); for scope in scopes.iter() { @@ -323,30 +384,28 @@ pub fn do_branding(gen: &GeneratorContext, for _ in params.iter() { arguments.push("::capnp::any_pointer::Owned".to_string()); } - }, - Some(scope) => { - match scope.which()? { - brand::scope::Inherit(()) => { - for param in params.iter() { - arguments.push(param.get_name()?.to_string()); - } + } + Some(scope) => match scope.which()? { + brand::scope::Inherit(()) => { + for param in params.iter() { + arguments.push(param.get_name()?.to_string()); } - brand::scope::Bind(bindings_list_opt) => { - let bindings_list = bindings_list_opt?; - assert_eq!(bindings_list.len(), params.len()); - for binding in bindings_list.iter() { - match binding.which()? { - brand::binding::Unbound(()) => { - arguments.push("::capnp::any_pointer::Owned".to_string()); - } - brand::binding::Type(t) => { - arguments.push(t?.type_string(gen, Leaf::Owned)?); - } + } + brand::scope::Bind(bindings_list_opt) => { + let bindings_list = bindings_list_opt?; + assert_eq!(bindings_list.len(), params.len()); + for binding in bindings_list.iter() { + match binding.which()? { + brand::binding::Unbound(()) => { + arguments.push("::capnp::any_pointer::Owned".to_string()); + } + brand::binding::Type(t) => { + arguments.push(t?.type_string(gen, Leaf::Owned)?); } } } } - } + }, } accumulator.push(arguments); current_node_id = current_node.get_scope_id(); @@ -359,8 +418,8 @@ pub fn do_branding(gen: &GeneratorContext, // Now add a lifetime parameter if the leaf has one. match leaf { - Leaf::Reader(lt) => accumulator.push(vec!(lt.to_string())), - Leaf::Builder(lt) => accumulator.push(vec!(lt.to_string())), + Leaf::Reader(lt) => accumulator.push(vec![lt.to_string()]), + Leaf::Builder(lt) => accumulator.push(vec![lt.to_string()]), Leaf::ServerDispatch => accumulator.push(vec!["_T".to_string()]), // HACK _ => (), } @@ -382,11 +441,11 @@ pub fn do_branding(gen: &GeneratorContext, arguments = arguments)) } - - -pub fn get_type_parameters(gen: &GeneratorContext, - node_id: u64, - mut parent_scope_id: Option) -> Vec { +pub fn get_type_parameters( + gen: &GeneratorContext, + node_id: u64, + mut parent_scope_id: Option, +) -> Vec { let mut current_node_id = node_id; let mut accumulator: Vec> = Vec::new(); loop { diff --git a/capnpc/src/lib.rs b/capnpc/src/lib.rs index f7c92b00f..f31de9927 100644 --- a/capnpc/src/lib.rs +++ b/capnpc/src/lib.rs @@ -72,17 +72,23 @@ pub(crate) fn convert_io_err(err: std::io::Error) -> capnp::Error { use std::io; let kind = match err.kind() { io::ErrorKind::TimedOut => capnp::ErrorKind::Overloaded, - io::ErrorKind::BrokenPipe | - io::ErrorKind::ConnectionRefused | - io::ErrorKind::ConnectionReset | - io::ErrorKind::ConnectionAborted | - io::ErrorKind::NotConnected => capnp::ErrorKind::Disconnected, + io::ErrorKind::BrokenPipe + | io::ErrorKind::ConnectionRefused + | io::ErrorKind::ConnectionReset + | io::ErrorKind::ConnectionAborted + | io::ErrorKind::NotConnected => capnp::ErrorKind::Disconnected, _ => capnp::ErrorKind::Failed, }; - capnp::Error { description: format!("{}", err), kind } + capnp::Error { + description: format!("{}", err), + kind, + } } -fn run_command(mut command: ::std::process::Command, mut code_generation_command: codegen::CodeGenerationCommand) -> ::capnp::Result<()> { +fn run_command( + mut command: ::std::process::Command, + mut code_generation_command: codegen::CodeGenerationCommand, +) -> ::capnp::Result<()> { let mut p = command.spawn().map_err(convert_io_err)?; code_generation_command.run(p.stdout.take().unwrap())?; let exit_status = p.wait().map_err(convert_io_err)?; @@ -172,7 +178,7 @@ impl CompilerCommand { /// on the system (e.g. in working directory or in PATH environment variable). pub fn capnp_executable

(&mut self, path: P) -> &mut CompilerCommand where - P: AsRef + P: AsRef, { self.executable_path = Some(path.as_ref().to_path_buf()); self @@ -196,8 +202,10 @@ impl CompilerCommand { /// This option can be overridden by the `parentModule` annotation defined in `rust.capnp`. /// /// If this option is unset, the default is the crate root. - pub fn default_parent_module(&mut self, default_parent_module: Vec) -> &mut CompilerCommand - { + pub fn default_parent_module( + &mut self, + default_parent_module: Vec, + ) -> &mut CompilerCommand { self.default_parent_module = default_parent_module; self } @@ -276,7 +284,8 @@ impl CompilerCommand { .output_directory(output_path) .default_parent_module(self.default_parent_module.clone()); if let Some(raw_code_generator_request_path) = &self.raw_code_generator_request_path { - code_generation_command.raw_code_generator_request_path(raw_code_generator_request_path.clone()); + code_generation_command + .raw_code_generator_request_path(raw_code_generator_request_path.clone()); } run_command(command, code_generation_command).map_err(|error| { @@ -298,6 +307,10 @@ fn compiler_command_new_no_out_dir() { #[test] fn compiler_command_with_output_path_no_out_dir() { - let error = CompilerCommand::new().output_path("foo").run().unwrap_err().description; + let error = CompilerCommand::new() + .output_path("foo") + .run() + .unwrap_err() + .description; assert!(error.starts_with("Error while trying to execute `capnp compile`")); } diff --git a/capnpc/src/pointer_constants.rs b/capnpc/src/pointer_constants.rs index afe5d60fc..22b81e8bd 100644 --- a/capnpc/src/pointer_constants.rs +++ b/capnpc/src/pointer_constants.rs @@ -20,39 +20,48 @@ use capnp::{any_pointer, message}; +use crate::codegen::FormattedText::{Branch, Indent, Line}; use crate::codegen::{FormattedText, GeneratorContext}; -use crate::codegen::FormattedText::{Indent, Line, Branch}; -use crate::codegen_types::{ Leaf, RustTypeInfo }; -use crate::schema_capnp::{type_}; +use crate::codegen_types::{Leaf, RustTypeInfo}; +use crate::schema_capnp::type_; pub struct WordArrayDeclarationOptions { pub public: bool, pub omit_first_word: bool, } -pub fn word_array_declaration(name: &str, - value: any_pointer::Reader, - options: WordArrayDeclarationOptions) -> ::capnp::Result { +pub fn word_array_declaration( + name: &str, + value: any_pointer::Reader, + options: WordArrayDeclarationOptions, +) -> ::capnp::Result { let allocator = message::HeapAllocator::new() .first_segment_words(value.target_size()?.word_count as u32 + 1); let mut message = message::Builder::new(allocator); message.set_root(value)?; let mut words = message.get_segments_for_output()[0]; - if options.omit_first_word { words = &words[8..] } + if options.omit_first_word { + words = &words[8..] + } let mut words_lines = Vec::new(); for index in 0..(words.len() / 8) { - let bytes = &words[(index * 8)..(index +1)*8]; - words_lines.push(Line( - format!("capnp::word({}, {}, {}, {}, {}, {}, {}, {}),", - bytes[0], bytes[1], bytes[2], bytes[3], - bytes[4], bytes[5], bytes[6], bytes[7]))); + let bytes = &words[(index * 8)..(index + 1) * 8]; + words_lines.push(Line(format!( + "capnp::word({}, {}, {}, {}, {}, {}, {}, {}),", + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7] + ))); } let vis = if options.public { "pub " } else { "" }; Ok(Branch(vec![ - Line(format!("{}static {}: [capnp::Word; {}] = [", vis, name, words.len() / 8)), + Line(format!( + "{}static {}: [capnp::Word; {}] = [", + vis, + name, + words.len() / 8 + )), Indent(Box::new(Branch(words_lines))), - Line("];".to_string()) + Line("];".to_string()), ])) } @@ -60,14 +69,23 @@ pub fn generate_pointer_constant( gen: &GeneratorContext, styled_name: &str, typ: type_::Reader, - value: any_pointer::Reader) - -> ::capnp::Result -{ + value: any_pointer::Reader, +) -> ::capnp::Result { Ok(Branch(vec![ - Line(format!("pub static {}: ::capnp::constant::Reader<{}> = {{", - styled_name, typ.type_string(gen, Leaf::Owned)?)), + Line(format!( + "pub static {}: ::capnp::constant::Reader<{}> = {{", + styled_name, + typ.type_string(gen, Leaf::Owned)? + )), Indent(Box::new(Branch(vec![ - word_array_declaration("WORDS", value, WordArrayDeclarationOptions { public: false, omit_first_word: false })?, + word_array_declaration( + "WORDS", + value, + WordArrayDeclarationOptions { + public: false, + omit_first_word: false, + }, + )?, Line("::capnp::constant::Reader {".into()), Indent(Box::new(Branch(vec![ Line("phantom: ::std::marker::PhantomData,".into()), @@ -75,6 +93,6 @@ pub fn generate_pointer_constant( ]))), Line("}".into()), ]))), - Line("};".to_string()) + Line("};".to_string()), ])) } diff --git a/capnpc/test-edition-2015/build.rs b/capnpc/test-edition-2015/build.rs index 4af133023..3fa6d0aa9 100644 --- a/capnpc/test-edition-2015/build.rs +++ b/capnpc/test-edition-2015/build.rs @@ -1,5 +1,5 @@ fn main() { - capnpc::CompilerCommand::new() + capnpc::CompilerCommand::new() .file("../test/test.capnp") .src_prefix("../test/") .run() diff --git a/capnpc/test-edition-2015/test.rs b/capnpc/test-edition-2015/test.rs index 5ae3ac22a..367209a33 100644 --- a/capnpc/test-edition-2015/test.rs +++ b/capnpc/test-edition-2015/test.rs @@ -1,5 +1,5 @@ -extern crate core; extern crate capnp; +extern crate core; pub mod test_capnp { include!(concat!(env!("OUT_DIR"), "/test_capnp.rs")); diff --git a/capnpc/test-edition-2018/build.rs b/capnpc/test-edition-2018/build.rs index 4af133023..3fa6d0aa9 100644 --- a/capnpc/test-edition-2018/build.rs +++ b/capnpc/test-edition-2018/build.rs @@ -1,5 +1,5 @@ fn main() { - capnpc::CompilerCommand::new() + capnpc::CompilerCommand::new() .file("../test/test.capnp") .src_prefix("../test/") .run() diff --git a/capnpc/test-edition-2021/build.rs b/capnpc/test-edition-2021/build.rs index 4af133023..3fa6d0aa9 100644 --- a/capnpc/test-edition-2021/build.rs +++ b/capnpc/test-edition-2021/build.rs @@ -1,5 +1,5 @@ fn main() { - capnpc::CompilerCommand::new() + capnpc::CompilerCommand::new() .file("../test/test.capnp") .src_prefix("../test/") .run() diff --git a/capnpc/test/build.rs b/capnpc/test/build.rs index 8a5a007f0..290b114e0 100644 --- a/capnpc/test/build.rs +++ b/capnpc/test/build.rs @@ -1,5 +1,5 @@ fn main() { - capnpc::CompilerCommand::new() + capnpc::CompilerCommand::new() .file("test.capnp") .file("in-submodule.capnp") .file("in-other-submodule.capnp") @@ -16,9 +16,10 @@ fn main() { capnpc::CompilerCommand::new() .file("test-default-parent-module.capnp") .file("test-default-parent-module-override.capnp") - .default_parent_module(vec!["test_default_parent_module".into(), - "test_default_parent_module_inner".into()]) + .default_parent_module(vec![ + "test_default_parent_module".into(), + "test_default_parent_module_inner".into(), + ]) .run() .expect("compiling schema"); - } diff --git a/capnpc/test/test.rs b/capnpc/test/test.rs index 5b2670e01..1cb7d9223 100644 --- a/capnpc/test/test.rs +++ b/capnpc/test/test.rs @@ -44,16 +44,21 @@ pub mod test_default_parent_module { pub mod test_default_parent_module_inner { // In build.rs we specify this is the default parent module. pub mod test_default_parent_module_capnp { - include!(concat!(env!("OUT_DIR"), "/test_default_parent_module_capnp.rs")); + include!(concat!( + env!("OUT_DIR"), + "/test_default_parent_module_capnp.rs" + )); } } // Put this in somewhere other than the default parent module, to test whether the `parentModule` // annotation successfully overrides the default. pub mod test_default_parent_module_override_capnp { - include!(concat!(env!("OUT_DIR"), "/test_default_parent_module_override_capnp.rs")); + include!(concat!( + env!("OUT_DIR"), + "/test_default_parent_module_override_capnp.rs" + )); } - } pub mod test_in_dir_capnp { @@ -61,8 +66,8 @@ pub mod test_in_dir_capnp { } pub mod test_in_src_prefix_dir_capnp { - // The src_prefix gets stripped away, so the generated code ends up directly in OUT_DIR. - include!(concat!(env!("OUT_DIR"), "/test_in_src_prefix_dir_capnp.rs")); + // The src_prefix gets stripped away, so the generated code ends up directly in OUT_DIR. + include!(concat!(env!("OUT_DIR"), "/test_in_src_prefix_dir_capnp.rs")); } #[cfg(test)] @@ -70,16 +75,17 @@ mod test_util; #[cfg(test)] mod tests { + use crate::test_util::{init_test_message, CheckTestMessage}; + use capnp::message::ReaderOptions; use capnp::message::{self, TypedBuilder, TypedReader}; - use capnp::message::{ReaderOptions}; - use crate::test_util::{CheckTestMessage, init_test_message}; #[test] - fn test_prim_list () { + fn test_prim_list() { use crate::test_capnp::test_prim_list; // Make the first segment small to force allocation of a second segment. - let mut message = message::Builder::new(message::HeapAllocator::new().first_segment_words(50)); + let mut message = + message::Builder::new(message::HeapAllocator::new().first_segment_words(50)); let mut test_prim_list = message.init_root::>(); assert_eq!(test_prim_list.has_bool_list(), false); @@ -156,7 +162,7 @@ mod tests { } #[test] - fn test_struct_list () { + fn test_struct_list() { use crate::test_capnp::test_struct_list; let mut message = message::Builder::new(message::HeapAllocator::new()); @@ -171,12 +177,21 @@ mod tests { { let reader = test_struct_list.into_reader(); - assert_eq!(reader.get_struct_list().unwrap().get(0).get_uint8_list().unwrap().get(0), 5u8); + assert_eq!( + reader + .get_struct_list() + .unwrap() + .get(0) + .get_uint8_list() + .unwrap() + .get(0), + 5u8 + ); } } #[test] - fn test_blob () { + fn test_blob() { use crate::test_capnp::test_blob; let mut message = message::Builder::new(message::HeapAllocator::new()); @@ -202,13 +217,15 @@ mod tests { { let mut text = test_blob.reborrow().init_text_field(10); - assert_eq!(&*text,"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); + assert_eq!(&*text, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); text.push_str("aabbccddee"); } test_blob.reborrow().init_data_field(7); - assert!(test_blob.reborrow().into_reader().get_data_field().unwrap() == - [0u8,0u8,0u8,0u8,0u8,0u8,0u8]); + assert!( + test_blob.reborrow().into_reader().get_data_field().unwrap() + == [0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8] + ); { let data_builder = test_blob.reborrow().get_data_field().unwrap(); for c in data_builder.iter_mut() { @@ -217,22 +234,31 @@ mod tests { data_builder[0] = 4u8; } - assert_eq!(test_blob.reborrow().into_reader().get_text_field().unwrap(), "aabbccddee"); - assert!(test_blob.reborrow().into_reader().get_data_field().unwrap() == [4u8,5u8,5u8,5u8,5u8,5u8,5u8]); + assert_eq!( + test_blob.reborrow().into_reader().get_text_field().unwrap(), + "aabbccddee" + ); + assert!( + test_blob.reborrow().into_reader().get_data_field().unwrap() + == [4u8, 5u8, 5u8, 5u8, 5u8, 5u8, 5u8] + ); { test_blob.reborrow().get_data_field().unwrap()[2] = 10; } - assert!(test_blob.into_reader().get_data_field().unwrap() == [4u8,5u8,10u8,5u8,5u8,5u8,5u8]); + assert!( + test_blob.into_reader().get_data_field().unwrap() + == [4u8, 5u8, 10u8, 5u8, 5u8, 5u8, 5u8] + ); } - #[test] fn test_big_struct() { use crate::test_capnp::test_big_struct; // Make the first segment small to force allocation of a second segment. - let mut message = message::Builder::new(message::HeapAllocator::new().first_segment_words(5)); + let mut message = + message::Builder::new(message::HeapAllocator::new().first_segment_words(5)); let mut big_struct = message.init_root::>(); @@ -252,7 +278,6 @@ mod tests { big_struct.set_bool_field(true); - let big_struct_reader = big_struct.into_reader(); assert_eq!(big_struct_reader.has_struct_field(), true); assert_eq!(big_struct_reader.get_int8_field(), -128); @@ -265,7 +290,7 @@ mod tests { } #[test] - fn test_complex_list () { + fn test_complex_list() { use crate::test_capnp::{test_complex_list, AnEnum}; let mut message = message::Builder::new_default(); @@ -305,11 +330,12 @@ mod tests { assert_eq!(prim_list.len(), 3); } let mut prim_list = prim_list_list.init(1, 1); - prim_list.set(0,-1); + prim_list.set(0, -1); } { - let mut prim_list_list_list = test_complex_list.reborrow().init_prim_list_list_list(2); + let mut prim_list_list_list = + test_complex_list.reborrow().init_prim_list_list_list(2); { let mut prim_list_list = prim_list_list_list.reborrow().init(0, 2); { @@ -340,17 +366,17 @@ mod tests { { let text_list_list = test_complex_list.reborrow().init_text_list_list(1); - text_list_list.init(0,1).set(0, "abc"); + text_list_list.init(0, 1).set(0, "abc"); } { let data_list_list = test_complex_list.reborrow().init_data_list_list(1); - data_list_list.init(0,1).set(0, &[255, 254, 253]); + data_list_list.init(0, 1).set(0, &[255, 254, 253]); } { let struct_list_list = test_complex_list.reborrow().init_struct_list_list(1); - struct_list_list.init(0,1).get(0).set_int8_field(-1); + struct_list_list.init(0, 1).get(0).set_int8_field(-1); } } @@ -394,15 +420,42 @@ mod tests { assert!(enum_list_list.get(1).unwrap().get(0) == Ok(AnEnum::Foo)); assert!(enum_list_list.get(1).unwrap().get(1) == Ok(AnEnum::Qux)); - assert!(complex_list_reader.get_text_list_list().unwrap().get(0).unwrap().get(0).unwrap() == "abc"); - assert!(complex_list_reader.get_data_list_list().unwrap().get(0).unwrap().get(0).unwrap() == [255, 254, 253]); + assert!( + complex_list_reader + .get_text_list_list() + .unwrap() + .get(0) + .unwrap() + .get(0) + .unwrap() + == "abc" + ); + assert!( + complex_list_reader + .get_data_list_list() + .unwrap() + .get(0) + .unwrap() + .get(0) + .unwrap() + == [255, 254, 253] + ); - assert!(complex_list_reader.get_struct_list_list().unwrap().get(0).unwrap().get(0).get_int8_field() == -1); + assert!( + complex_list_reader + .get_struct_list_list() + .unwrap() + .get(0) + .unwrap() + .get(0) + .get_int8_field() + == -1 + ); } #[test] - fn test_list_list_set_elem () { - use crate::test_capnp::{test_complex_list}; + fn test_list_list_set_elem() { + use crate::test_capnp::test_complex_list; let mut message1 = message::Builder::new_default(); let mut message2 = message::Builder::new_default(); @@ -420,7 +473,9 @@ mod tests { prim_list1.set(2, 9); assert_eq!(prim_list1.len(), 3); - prim_list_list2.set(0, prim_list1.reborrow().into_reader()).unwrap(); + prim_list_list2 + .set(0, prim_list1.reborrow().into_reader()) + .unwrap(); let prim_list2 = prim_list_list2.get(0).unwrap(); assert_eq!(prim_list2.len(), 3); @@ -437,7 +492,8 @@ mod tests { { let message = message::Builder::new_default(); - let test_defaults = message.get_root_as_reader::>() + let test_defaults = message + .get_root_as_reader::>() .expect("get_root_as_reader()"); CheckTestMessage::check_test_message(test_defaults); } @@ -450,7 +506,8 @@ mod tests { { let mut message = message::Builder::new_default(); - let mut test_defaults = message.get_root::>() + let mut test_defaults = message + .get_root::>() .expect("get_root()"); test_defaults.set_bool_field(false); test_defaults.set_int8_field(63); @@ -472,12 +529,15 @@ mod tests { assert_eq!(test_defaults.reborrow().get_bool_field(), false); assert_eq!(test_defaults.reborrow().get_int8_field(), 63); assert_eq!(test_defaults.reborrow().get_int16_field(), -1123); - assert_eq!(test_defaults.reborrow().get_int32_field(), 445678); + assert_eq!(test_defaults.reborrow().get_int32_field(), 445678); assert_eq!(test_defaults.reborrow().get_int64_field(), -990123456789); assert_eq!(test_defaults.reborrow().get_u_int8_field(), 234); assert_eq!(test_defaults.reborrow().get_u_int16_field(), 56789); - assert_eq!(test_defaults.reborrow().get_u_int32_field(), 123456789); - assert_eq!(test_defaults.reborrow().get_u_int64_field(), 123456789012345); + assert_eq!(test_defaults.reborrow().get_u_int32_field(), 123456789); + assert_eq!( + test_defaults.reborrow().get_u_int64_field(), + 123456789012345 + ); assert_eq!(test_defaults.reborrow().get_float32_field(), 7890.123); assert_eq!(test_defaults.reborrow().get_float64_field(), 5e55); @@ -492,7 +552,8 @@ mod tests { fn test_default_initialization_multi_segment() { use crate::test_capnp::test_defaults; let builder_options = message::HeapAllocator::new() - .first_segment_words(1).allocation_strategy(::capnp::message::AllocationStrategy::FixedSize); + .first_segment_words(1) + .allocation_strategy(::capnp::message::AllocationStrategy::FixedSize); let mut message = message::Builder::new(builder_options); let test_defaults = message.init_root::>(); CheckTestMessage::check_test_message(test_defaults); @@ -500,31 +561,54 @@ mod tests { #[test] fn test_any_pointer() { - use crate::test_capnp::{test_any_pointer, test_empty_struct, test_big_struct}; + use crate::test_capnp::{test_any_pointer, test_big_struct, test_empty_struct}; let mut message = message::Builder::new_default(); let mut test_any_pointer = message.init_root::>(); - test_any_pointer.reborrow().init_any_pointer_field().set_as("xyzzy").unwrap(); + test_any_pointer + .reborrow() + .init_any_pointer_field() + .set_as("xyzzy") + .unwrap(); { let reader = test_any_pointer.reborrow().into_reader(); - assert_eq!(reader.get_any_pointer_field().get_as::<::capnp::text::Reader<'_>>().unwrap(), "xyzzy"); - } - - test_any_pointer.reborrow().get_any_pointer_field().init_as::>(); - test_any_pointer.reborrow().get_any_pointer_field().get_as::>().unwrap(); + assert_eq!( + reader + .get_any_pointer_field() + .get_as::<::capnp::text::Reader<'_>>() + .unwrap(), + "xyzzy" + ); + } + + test_any_pointer + .reborrow() + .get_any_pointer_field() + .init_as::>(); + test_any_pointer + .reborrow() + .get_any_pointer_field() + .get_as::>() + .unwrap(); { let reader = test_any_pointer.reborrow().into_reader(); - reader.get_any_pointer_field().get_as::>().unwrap(); + reader + .get_any_pointer_field() + .get_as::>() + .unwrap(); } { let mut message = message::Builder::new_default(); let mut test_big_struct = message.init_root::>(); test_big_struct.set_int32_field(-12345); - test_any_pointer.get_any_pointer_field().set_as(test_big_struct.reborrow().into_reader()).unwrap(); + test_any_pointer + .get_any_pointer_field() + .set_as(test_big_struct.reborrow().into_reader()) + .unwrap(); } fn _test_lifetimes(body: test_big_struct::Reader<'_>) { @@ -540,8 +624,7 @@ mod tests { let mut message = message::Builder::new_default(); let mut big_struct = message.init_root::>(); - - let neg_seven : u64 = (-7i64) as u64; + let neg_seven: u64 = (-7i64) as u64; { let mut struct_field = big_struct.reborrow().init_struct_field(); assert_eq!(struct_field.reborrow().get_uint64_field(), 0); @@ -549,7 +632,14 @@ mod tests { struct_field.set_uint64_field(neg_seven); assert_eq!(struct_field.get_uint64_field(), neg_seven); } - assert_eq!(big_struct.reborrow().get_struct_field().unwrap().get_uint64_field(), neg_seven); + assert_eq!( + big_struct + .reborrow() + .get_struct_field() + .unwrap() + .get_uint64_field(), + neg_seven + ); { let mut struct_field = big_struct.reborrow().init_struct_field(); assert_eq!(struct_field.reborrow().get_uint64_field(), 0); @@ -558,25 +648,70 @@ mod tests { { // getting before init is the same as init - assert_eq!(big_struct.reborrow().get_another_struct_field().unwrap().get_uint64_field(), 0); - big_struct.reborrow().get_another_struct_field().unwrap().set_uint32_field(4294967265); + assert_eq!( + big_struct + .reborrow() + .get_another_struct_field() + .unwrap() + .get_uint64_field(), + 0 + ); + big_struct + .reborrow() + .get_another_struct_field() + .unwrap() + .set_uint32_field(4294967265); // Alas, we need to make a copy to appease the reborrow checker. let mut other_message = message::Builder::new_default(); - other_message.set_root(big_struct.reborrow().get_another_struct_field().unwrap().into_reader()).unwrap(); - big_struct.set_struct_field( - other_message.get_root::>().unwrap().into_reader()).unwrap(); - } - - assert_eq!(big_struct.reborrow().get_struct_field().unwrap().get_uint32_field(), 4294967265); + other_message + .set_root( + big_struct + .reborrow() + .get_another_struct_field() + .unwrap() + .into_reader(), + ) + .unwrap(); + big_struct + .set_struct_field( + other_message + .get_root::>() + .unwrap() + .into_reader(), + ) + .unwrap(); + } + + assert_eq!( + big_struct + .reborrow() + .get_struct_field() + .unwrap() + .get_uint32_field(), + 4294967265 + ); { let mut other_struct_field = big_struct.reborrow().get_another_struct_field().unwrap(); assert_eq!(other_struct_field.reborrow().get_uint32_field(), 4294967265); other_struct_field.set_uint32_field(42); assert_eq!(other_struct_field.get_uint32_field(), 42); } - assert_eq!(big_struct.reborrow().get_struct_field().unwrap().get_uint32_field(), 4294967265); - assert_eq!(big_struct.get_another_struct_field().unwrap().get_uint32_field(), 42); + assert_eq!( + big_struct + .reborrow() + .get_struct_field() + .unwrap() + .get_uint32_field(), + 4294967265 + ); + assert_eq!( + big_struct + .get_another_struct_field() + .unwrap() + .get_uint32_field(), + 42 + ); } #[test] @@ -592,7 +727,16 @@ mod tests { } let reader = branded.into_reader(); - assert_eq!("blah", reader.get_branded_field().unwrap().get_generic_field().unwrap().get_text_field().unwrap()); + assert_eq!( + "blah", + reader + .get_branded_field() + .unwrap() + .get_generic_field() + .unwrap() + .get_text_field() + .unwrap() + ); } #[test] @@ -610,21 +754,44 @@ mod tests { } let reader = branded.into_reader(); - assert_eq!("blah", reader.get_baz_field().unwrap().get_foo_field().unwrap()); - assert_eq!("some text", reader.get_baz_field().unwrap().get_bar_field().unwrap().get_text_field().unwrap()); - assert_eq!("some data".as_bytes(), reader.get_baz_field().unwrap().get_bar_field().unwrap().get_data_field().unwrap()); + assert_eq!( + "blah", + reader.get_baz_field().unwrap().get_foo_field().unwrap() + ); + assert_eq!( + "some text", + reader + .get_baz_field() + .unwrap() + .get_bar_field() + .unwrap() + .get_text_field() + .unwrap() + ); + assert_eq!( + "some data".as_bytes(), + reader + .get_baz_field() + .unwrap() + .get_bar_field() + .unwrap() + .get_data_field() + .unwrap() + ); } #[test] fn test_generics() { + use crate::test_capnp::{test_all_types, test_generics}; use capnp::text; - use crate::test_capnp::{test_generics, test_all_types}; let mut message = message::Builder::new_default(); - let mut root: test_generics::Builder<'_, test_all_types::Owned, text::Owned> = message.init_root(); + let mut root: test_generics::Builder<'_, test_all_types::Owned, text::Owned> = + message.init_root(); init_test_message(root.reborrow().get_foo().unwrap()); root.reborrow().get_dub().unwrap().set_foo("Hello").unwrap(); { - let mut bar: ::capnp::primitive_list::Builder<'_,u8> = root.reborrow().get_dub().unwrap().initn_bar(1); + let mut bar: ::capnp::primitive_list::Builder<'_, u8> = + root.reborrow().get_dub().unwrap().initn_bar(1); bar.set(0, 11); } { @@ -647,12 +814,15 @@ mod tests { #[test] fn test_generic_union() { + use crate::test_capnp::{test_all_types, test_generics_union}; use capnp::primitive_list; - use crate::test_capnp::{test_generics_union, test_all_types}; let mut message = message::Builder::new_default(); { - let mut root: test_generics_union::Builder<'_, test_all_types::Owned, primitive_list::Owned> - = message.init_root(); + let mut root: test_generics_union::Builder< + '_, + test_all_types::Owned, + primitive_list::Owned, + > = message.init_root(); { let mut bar = root.reborrow().initn_bar1(10); bar.set(5, 100); @@ -691,13 +861,16 @@ mod tests { #[test] fn test_generics_groups() { + use crate::test_capnp::{test_all_types, test_generics_groups}; use capnp::primitive_list; - use crate::test_capnp::{test_generics_groups, test_all_types}; { let mut message = message::Builder::new_default(); { - let mut root: test_generics_groups::Builder<'_, test_all_types::Owned, primitive_list::Owned> - = message.init_root(); + let mut root: test_generics_groups::Builder< + '_, + test_all_types::Owned, + primitive_list::Owned, + > = message.init_root(); { root.reborrow().get_foo().unwrap().set_int16_field(17); let mut bar = root.init_bar(); @@ -705,8 +878,11 @@ mod tests { baz.set(2, 11); } } - let root: test_generics_groups::Reader<'_, test_all_types::Owned, primitive_list::Owned> - = message.get_root_as_reader().unwrap(); + let root: test_generics_groups::Reader< + '_, + test_all_types::Owned, + primitive_list::Owned, + > = message.get_root_as_reader().unwrap(); assert_eq!(17, root.get_foo().unwrap().get_int16_field()); let baz = root.get_bar().get_baz().unwrap(); assert_eq!(5, baz.len()); @@ -716,12 +892,13 @@ mod tests { { let mut message = message::Builder::new_default(); { - let mut root: test_generics_groups::inner::Builder<'_, - test_all_types::Owned, - primitive_list::Owned, - primitive_list::Owned, - primitive_list::Owned> - = message.init_root(); + let mut root: test_generics_groups::inner::Builder< + '_, + test_all_types::Owned, + primitive_list::Owned, + primitive_list::Owned, + primitive_list::Owned, + > = message.init_root(); { let mut foo = root.reborrow().initn_foo(3); foo.set(1, -1025); @@ -730,12 +907,13 @@ mod tests { bar.set_baz(()); } } - let root: test_generics_groups::inner::Reader<'_, - test_all_types::Owned, - primitive_list::Owned, - primitive_list::Owned, - primitive_list::Owned> - = message.get_root_as_reader().unwrap(); + let root: test_generics_groups::inner::Reader< + '_, + test_all_types::Owned, + primitive_list::Owned, + primitive_list::Owned, + primitive_list::Owned, + > = message.get_root_as_reader().unwrap(); let foo = root.get_foo().unwrap(); assert_eq!(3, foo.len()); assert_eq!(-1025, foo.get(1)); @@ -756,17 +934,17 @@ mod tests { union_struct.reborrow().get_union0().set_u0f0s0(()); match union_struct.reborrow().get_union0().which() { Ok(test_union::union0::U0f0s0(())) => {} - _ => panic!() + _ => panic!(), } union_struct.reborrow().init_union0().set_u0f0s1(true); match union_struct.reborrow().get_union0().which() { Ok(test_union::union0::U0f0s1(true)) => {} - _ => panic!() + _ => panic!(), } union_struct.reborrow().init_union0().set_u0f0s8(127); match union_struct.reborrow().get_union0().which() { Ok(test_union::union0::U0f0s8(127)) => {} - _ => panic!() + _ => panic!(), } assert_eq!(union_struct.reborrow().get_union0().has_u0f0sp(), false); @@ -780,18 +958,24 @@ mod tests { { let message = message::Builder::new_default(); - let reader = message.get_root_as_reader::>() + let reader = message + .get_root_as_reader::>() .expect("get_root_as_reader()"); let field = reader.get_s16s8s64s8_set().unwrap(); - if let test_union::union0::U0f0s16(_) = field.get_union0().which().unwrap() {} else { + if let test_union::union0::U0f0s16(_) = field.get_union0().which().unwrap() { + } else { panic!("expected U0f0s16"); } - if let test_union_defaults::inner1::A(17) = reader.get_inner1().which().unwrap() {} else { + if let test_union_defaults::inner1::A(17) = reader.get_inner1().which().unwrap() { + } else { panic!("") } - if let test_union_defaults::inner2::C(Ok("grault")) = reader.get_inner2().which().unwrap() {} else { + if let test_union_defaults::inner2::C(Ok("grault")) = + reader.get_inner2().which().unwrap() + { + } else { panic!("") } } @@ -827,7 +1011,14 @@ mod tests { { let sub_reader = struct_const_root.get_struct_field().unwrap(); assert_eq!(sub_reader.get_text_field().unwrap(), "nested"); - assert_eq!(sub_reader.get_struct_field().unwrap().get_text_field().unwrap(), "really nested"); + assert_eq!( + sub_reader + .get_struct_field() + .unwrap() + .get_text_field() + .unwrap(), + "really nested" + ); } // ... } @@ -886,7 +1077,7 @@ mod tests { #[test] fn upgrade_struct() { - use crate::test_capnp::{test_old_version, test_new_version}; + use crate::test_capnp::{test_new_version, test_old_version}; let mut message = message::Builder::new_default(); { @@ -902,7 +1093,7 @@ mod tests { #[test] fn upgrade_union() { - use crate::test_capnp::{test_old_union_version, test_new_union_version}; + use crate::test_capnp::{test_new_union_version, test_old_union_version}; // This tests for a specific case that was broken originally. let mut message = message::Builder::new_default(); { @@ -911,7 +1102,9 @@ mod tests { } { - let new_version = message.get_root::>().unwrap(); + let new_version = message + .get_root::>() + .unwrap(); match new_version.which().unwrap() { test_new_union_version::B(n) => assert_eq!(n, 123), _ => panic!("expected B"), @@ -927,15 +1120,19 @@ mod tests { let mut builder = message::Builder::new_default(); let mut root = builder.init_root::>(); { - let mut list = root.reborrow() - .get_any_pointer_field().initn_as::<::capnp::primitive_list::Builder<'_,u8>>(3); + let mut list = root + .reborrow() + .get_any_pointer_field() + .initn_as::<::capnp::primitive_list::Builder<'_, u8>>(3); list.set(0, 12); list.set(1, 34); list.set(2, 56); } { - let mut l = root.get_any_pointer_field() - .get_as::<::capnp::struct_list::Builder<'_,test_lists::struct8::Owned>>().unwrap(); + let mut l = root + .get_any_pointer_field() + .get_as::<::capnp::struct_list::Builder<'_, test_lists::struct8::Owned>>() + .unwrap(); assert_eq!(3, l.len()); assert_eq!(12, l.reborrow().get(0).get_f()); assert_eq!(34, l.reborrow().get(1).get_f()); @@ -947,15 +1144,19 @@ mod tests { let mut builder = message::Builder::new_default(); let mut root = builder.init_root::>(); { - let mut list = root.reborrow() - .get_any_pointer_field().initn_as::<::capnp::text_list::Builder<'_>>(3); + let mut list = root + .reborrow() + .get_any_pointer_field() + .initn_as::<::capnp::text_list::Builder<'_>>(3); list.set(0, "foo"); list.set(1, "bar"); list.set(2, "baz"); } { - let mut l = root.get_any_pointer_field() - .get_as::<::capnp::struct_list::Builder<'_,test_lists::struct_p::Owned>>().unwrap(); + let mut l = root + .get_any_pointer_field() + .get_as::<::capnp::struct_list::Builder<'_, test_lists::struct_p::Owned>>() + .unwrap(); assert_eq!(3, l.len()); assert_eq!("foo", &*l.reborrow().get(0).get_f().unwrap()); assert_eq!("bar", &*l.reborrow().get(1).get_f().unwrap()); @@ -966,23 +1167,26 @@ mod tests { #[test] fn upgrade_struct_list() { + use crate::test_capnp::{test_new_version, test_old_version}; use capnp::struct_list; - use crate::test_capnp::{test_old_version, test_new_version}; let segment0: &[capnp::Word] = &[ - capnp::word(1,0,0,0,0x1f,0,0,0), // list, inline composite, 3 words + capnp::word(1, 0, 0, 0, 0x1f, 0, 0, 0), // list, inline composite, 3 words capnp::word(4, 0, 0, 0, 1, 0, 2, 0), // struct tag. 1 element, 1 word data, 2 pointers. - capnp::word(0xab,0,0,0,0,0,0,0), - capnp::word(0x05,0,0,0, 0x42,0,0,0), // list pointer, offset 1, type = BYTE, length 8. - capnp::word(0,0,0,0,0,0,0,0), - capnp::word(0x68,0x65,0x6c,0x6c,0x6f,0x21,0x21,0), // "hello!!" + capnp::word(0xab, 0, 0, 0, 0, 0, 0, 0), + capnp::word(0x05, 0, 0, 0, 0x42, 0, 0, 0), // list pointer, offset 1, type = BYTE, length 8. + capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + capnp::word(0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0x21, 0), // "hello!!" ]; let segment_array = &[capnp::Word::words_to_bytes(segment0)]; - let message_reader = - message::Reader::new(message::SegmentArray::new(segment_array), ReaderOptions::new()); + let message_reader = message::Reader::new( + message::SegmentArray::new(segment_array), + ReaderOptions::new(), + ); - let old_version: struct_list::Reader<'_,test_old_version::Owned> = message_reader.get_root().unwrap(); + let old_version: struct_list::Reader<'_, test_old_version::Owned> = + message_reader.get_root().unwrap(); assert_eq!(old_version.len(), 1); assert_eq!(old_version.get(0).get_old1(), 0xab); assert_eq!(old_version.get(0).get_old2().unwrap(), "hello!!"); @@ -1000,10 +1204,14 @@ mod tests { } { - let mut new_version: struct_list::Builder<'_,test_new_version::Owned> = message.get_root().unwrap(); + let mut new_version: struct_list::Builder<'_, test_new_version::Owned> = + message.get_root().unwrap(); assert_eq!(new_version.len(), 1); assert_eq!(new_version.reborrow().get(0).get_old1(), 0xab); - assert_eq!(&*new_version.reborrow().get(0).get_old2().unwrap(), "hello!!"); + assert_eq!( + &*new_version.reborrow().get(0).get_old2().unwrap(), + "hello!!" + ); } { @@ -1011,36 +1219,48 @@ mod tests { // Check the old list, including the tag, was zeroed. assert_eq!(&segments[0][8..40], &[0; 32][..]); } - } #[test] fn all_types() { - use crate::test_capnp::{test_all_types}; + use crate::test_capnp::test_all_types; let mut message = message::Builder::new_default(); init_test_message(message.init_root()); - CheckTestMessage::check_test_message(message.get_root::>().unwrap()); CheckTestMessage::check_test_message( - message.get_root::>().unwrap().into_reader()); + message.get_root::>().unwrap(), + ); + CheckTestMessage::check_test_message( + message + .get_root::>() + .unwrap() + .into_reader(), + ); } #[test] fn all_types_multi_segment() { - use crate::test_capnp::{test_all_types}; + use crate::test_capnp::test_all_types; let builder_options = message::HeapAllocator::new() - .first_segment_words(1).allocation_strategy(::capnp::message::AllocationStrategy::FixedSize); + .first_segment_words(1) + .allocation_strategy(::capnp::message::AllocationStrategy::FixedSize); let mut message = message::Builder::new(builder_options); init_test_message(message.init_root()); - CheckTestMessage::check_test_message(message.get_root::>().unwrap()); CheckTestMessage::check_test_message( - message.get_root::>().unwrap().into_reader()); + message.get_root::>().unwrap(), + ); + CheckTestMessage::check_test_message( + message + .get_root::>() + .unwrap() + .into_reader(), + ); } #[test] fn setters() { - use crate::test_capnp::{test_all_types}; + use crate::test_capnp::test_all_types; { let mut message = message::Builder::new_default(); @@ -1050,7 +1270,14 @@ mod tests { let mut message2 = message::Builder::new_default(); let mut all_types2 = message2.init_root::>(); - all_types2.set_struct_field(message.get_root::>().unwrap().into_reader()).unwrap(); + all_types2 + .set_struct_field( + message + .get_root::>() + .unwrap() + .into_reader(), + ) + .unwrap(); CheckTestMessage::check_test_message(all_types2.reborrow().get_struct_field().unwrap()); let reader = all_types2.into_reader().get_struct_field().unwrap(); @@ -1071,7 +1298,9 @@ mod tests { let mut message2 = message::Builder::new(builder_options); let mut all_types2 = message2.init_root::>(); - all_types2.set_struct_field(message.get_root_as_reader().unwrap()).unwrap(); + all_types2 + .set_struct_field(message.get_root_as_reader().unwrap()) + .unwrap(); CheckTestMessage::check_test_message(all_types2.reborrow().get_struct_field().unwrap()); let reader = all_types2.into_reader().get_struct_field().unwrap(); @@ -1082,40 +1311,43 @@ mod tests { #[test] fn double_far_pointer() { let segment0: &[capnp::Word] = &[ - capnp::word(0,0,0,0,0,0,1,0), + capnp::word(0, 0, 0, 0, 0, 0, 1, 0), // struct pointer, zero offset, zero data words, one pointer. - - capnp::word(6,0,0,0,1,0,0,0), + capnp::word(6, 0, 0, 0, 1, 0, 0, 0), // far pointer, two-word landing pad, offset 0, segment 1. ]; let segment1: &[capnp::Word] = &[ - capnp::word(2,0,0,0,2,0,0,0), + capnp::word(2, 0, 0, 0, 2, 0, 0, 0), // landing pad start. offset 0, segment 2 - - capnp::word(0,0,0,0,1,0,1,0), + capnp::word(0, 0, 0, 0, 1, 0, 1, 0), // landing pad tag. struct pointer. One data word. One pointer. ]; let segment2: &[capnp::Word] = &[ - capnp::word(0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f), + capnp::word(0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f), // Data word. - - capnp::word(1,0,0,0,0x42,0,0,0), + capnp::word(1, 0, 0, 0, 0x42, 0, 0, 0), // text pointer. offset zero. 1-byte elements. 8 total elements. - - capnp::word('h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '.' as u8, '\n' as u8, 0), + capnp::word( + 'h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '.' as u8, '\n' as u8, 0, + ), ]; - let segment_array = &[capnp::Word::words_to_bytes(segment0), - capnp::Word::words_to_bytes(segment1), - capnp::Word::words_to_bytes(segment2)]; + let segment_array = &[ + capnp::Word::words_to_bytes(segment0), + capnp::Word::words_to_bytes(segment1), + capnp::Word::words_to_bytes(segment2), + ]; - let message = - message::Reader::new(message::SegmentArray::new(segment_array), ReaderOptions::new()); + let message = message::Reader::new( + message::SegmentArray::new(segment_array), + ReaderOptions::new(), + ); let root: crate::test_capnp::test_any_pointer::Reader<'_> = message.get_root().unwrap(); - let s: crate::test_capnp::test_all_types::Reader<'_> = root.get_any_pointer_field().get_as().unwrap(); + let s: crate::test_capnp::test_all_types::Reader<'_> = + root.get_any_pointer_field().get_as().unwrap(); assert_eq!(s.get_int8_field(), 0x1f); assert_eq!(s.get_int16_field(), 0x1f1f); assert_eq!(s.get_text_field().unwrap(), "hello.\n"); @@ -1124,25 +1356,27 @@ mod tests { #[test] fn double_far_pointer_truncated_pad() { let segment0: &[capnp::Word] = &[ - capnp::word(6,0,0,0,1,0,0,0), + capnp::word(6, 0, 0, 0, 1, 0, 0, 0), // far pointer, two-word landing pad, offset 0, segment 1. ]; let segment1: &[capnp::Word] = &[ - capnp::word(2,0,0,0,2,0,0,0), + capnp::word(2, 0, 0, 0, 2, 0, 0, 0), // landing pad start. offset 0, segment 2 // For this message to be valid, there would need to be another word here. ]; - let segment2: &[capnp::Word] = &[ - capnp::word(0,0,0,0,0,0,0,0), - ]; + let segment2: &[capnp::Word] = &[capnp::word(0, 0, 0, 0, 0, 0, 0, 0)]; - let segment_array = &[capnp::Word::words_to_bytes(segment0), - capnp::Word::words_to_bytes(segment1), - capnp::Word::words_to_bytes(segment2)]; - let message = - message::Reader::new(message::SegmentArray::new(segment_array), ReaderOptions::new()); + let segment_array = &[ + capnp::Word::words_to_bytes(segment0), + capnp::Word::words_to_bytes(segment1), + capnp::Word::words_to_bytes(segment2), + ]; + let message = message::Reader::new( + message::SegmentArray::new(segment_array), + ReaderOptions::new(), + ); match message.get_root::>() { Ok(_) => panic!("expected out-of-bounds error"), @@ -1155,26 +1389,27 @@ mod tests { #[test] fn double_far_pointer_out_of_bounds() { let segment0: &[capnp::Word] = &[ - capnp::word(6,0,0,0,1,0,0,0), + capnp::word(6, 0, 0, 0, 1, 0, 0, 0), // far pointer, two-word landing pad, offset 0, segment 1. ]; let segment1: &[capnp::Word] = &[ - capnp::word(0xa,0,0,0,2,0,0,0), + capnp::word(0xa, 0, 0, 0, 2, 0, 0, 0), // landing pad start. offset 1, segment 2 - - capnp::word(0,0,0,0,1,0,1,0), + capnp::word(0, 0, 0, 0, 1, 0, 1, 0), // landing pad tag. struct pointer. One data word. One pointer. ]; - let segment2: &[capnp::Word] = &[ - capnp::word(0,0,0,0,0,0,0,0), - ]; + let segment2: &[capnp::Word] = &[capnp::word(0, 0, 0, 0, 0, 0, 0, 0)]; - let segment_array = &[capnp::Word::words_to_bytes(segment0), - capnp::Word::words_to_bytes(segment1), - capnp::Word::words_to_bytes(segment2)]; - let message = - message::Reader::new(message::SegmentArray::new(segment_array), ReaderOptions::new()); + let segment_array = &[ + capnp::Word::words_to_bytes(segment0), + capnp::Word::words_to_bytes(segment1), + capnp::Word::words_to_bytes(segment2), + ]; + let message = message::Reader::new( + message::SegmentArray::new(segment_array), + ReaderOptions::new(), + ); match message.get_root::>() { Ok(_) => panic!("expected out-of-bounds error"), @@ -1188,24 +1423,28 @@ mod tests { fn far_pointer_pointing_at_self() { use crate::test_capnp::test_all_types; - let words: &[capnp::Word] = - &[capnp::word(0,0,0,0,0,0,1,0), // struct, one pointer - capnp::word(0xa,0,0,0,0,0,0,0)]; // far pointer, points to self + let words: &[capnp::Word] = &[ + capnp::word(0, 0, 0, 0, 0, 0, 1, 0), // struct, one pointer + capnp::word(0xa, 0, 0, 0, 0, 0, 0, 0), + ]; // far pointer, points to self let segment_array = &[capnp::Word::words_to_bytes(words)]; - let message_reader = - message::Reader::new(message::SegmentArray::new(segment_array), ReaderOptions::new()); + let message_reader = message::Reader::new( + message::SegmentArray::new(segment_array), + ReaderOptions::new(), + ); - let reader = message_reader.get_root::>().unwrap(); + let reader = message_reader + .get_root::>() + .unwrap(); assert!(reader.total_size().is_err()); let mut builder = ::capnp::message::Builder::new_default(); assert!(builder.set_root(reader).is_err()); } - #[test] fn text_builder_int_underflow() { - use crate::test_capnp::{test_any_pointer}; + use crate::test_capnp::test_any_pointer; let mut message = message::Builder::new_default(); { @@ -1213,7 +1452,9 @@ mod tests { let _: ::capnp::data::Builder<'_> = root.reborrow().get_any_pointer_field().initn_as(0); // No NUL terminator! - let result = root.get_any_pointer_field().get_as::<::capnp::text::Builder<'_>>(); + let result = root + .get_any_pointer_field() + .get_as::<::capnp::text::Builder<'_>>(); assert!(result.is_err()); } } @@ -1221,21 +1462,26 @@ mod tests { #[test] fn inline_composite_list_int_overflow() { let words: &[capnp::Word] = &[ - capnp::word(0,0,0,0,0,0,1,0), - capnp::word(1,0,0,0,0x17,0,0,0), - capnp::word(0,0,0,128,16,0,0,0), - capnp::word(0,0,0,0,0,0,0,0), - capnp::word(0,0,0,0,0,0,0,0)]; + capnp::word(0, 0, 0, 0, 0, 0, 1, 0), + capnp::word(1, 0, 0, 0, 0x17, 0, 0, 0), + capnp::word(0, 0, 0, 128, 16, 0, 0, 0), + capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; let segment_array = &[capnp::Word::words_to_bytes(words)]; - let message = - message::Reader::new(message::SegmentArray::new(segment_array), ReaderOptions::new()); + let message = message::Reader::new( + message::SegmentArray::new(segment_array), + ReaderOptions::new(), + ); let root: crate::test_capnp::test_any_pointer::Reader<'_> = message.get_root().unwrap(); match root.total_size() { - Err(e) => - assert_eq!("InlineComposite list's elements overrun its word count.", e.description), - _ => panic!("did not get expected error") + Err(e) => assert_eq!( + "InlineComposite list's elements overrun its word count.", + e.description + ), + _ => panic!("did not get expected error"), } { @@ -1246,17 +1492,20 @@ mod tests { } let mut message_builder = message::Builder::new_default(); - let builder_root = message_builder.init_root::>(); + let builder_root = + message_builder.init_root::>(); match builder_root.get_any_pointer_field().set_as(root) { - Err(e) => - assert_eq!("InlineComposite list's elements overrun its word count.", e.description), + Err(e) => assert_eq!( + "InlineComposite list's elements overrun its word count.", + e.description + ), _ => panic!("did not get expected error"), } } #[test] fn long_u64_list() { - use crate::test_capnp::{test_all_types}; + use crate::test_capnp::test_all_types; let length: u32 = 1 << 27; let step_exponent = 18; @@ -1278,7 +1527,7 @@ mod tests { let mut message2 = message::Builder::new_default(); { let root: test_all_types::Reader<'_> = message.get_root_as_reader().unwrap(); - let mut root2 : test_all_types::Builder<'_> = message2.init_root(); + let mut root2: test_all_types::Builder<'_> = message2.init_root(); let list = root.get_u_int64_list().unwrap(); @@ -1298,7 +1547,7 @@ mod tests { #[test] fn long_struct_list() { - use crate::test_capnp::{test_lists}; + use crate::test_capnp::test_lists; let length: u32 = 1 << 27; let step_exponent = 18; @@ -1327,7 +1576,7 @@ mod tests { #[test] fn long_list_list() { - use crate::test_capnp::{test_lists}; + use crate::test_capnp::test_lists; let length: u32 = 1 << 27; let step_exponent = 18; @@ -1360,14 +1609,16 @@ mod tests { #[test] fn traversal_limit_exceeded() { - use crate::test_capnp::{test_all_types}; + use crate::test_capnp::test_all_types; let mut message = message::Builder::new_default(); init_test_message(message.init_root()); let segments = message.get_segments_for_output(); - let reader = message::Reader::new(message::SegmentArray::new(&segments), - *ReaderOptions::new().traversal_limit_in_words(Some(2))); + let reader = message::Reader::new( + message::SegmentArray::new(&segments), + *ReaderOptions::new().traversal_limit_in_words(Some(2)), + ); match reader.get_root::>() { Err(e) => assert_eq!(e.description, "read limit exceeded"), Ok(_) => panic!("expected error"), @@ -1376,33 +1627,35 @@ mod tests { #[test] fn void_list_amplification() { - use crate::test_capnp::{test_any_pointer, test_all_types}; + use crate::test_capnp::{test_all_types, test_any_pointer}; let mut message = message::Builder::new_default(); { let root = message.init_root::>(); - let _: ::capnp::primitive_list::Builder<'_,()> = + let _: ::capnp::primitive_list::Builder<'_, ()> = root.get_any_pointer_field().initn_as((1 << 29) - 1); } let segments = message.get_segments_for_output(); assert_eq!(segments.len(), 1); assert_eq!(segments[0].len(), 16); // 2 words - let reader = message::Reader::new(message::SegmentArray::new(&segments), - ReaderOptions::new()); + let reader = + message::Reader::new(message::SegmentArray::new(&segments), ReaderOptions::new()); let root = reader.get_root::>().unwrap(); - let result = root.get_any_pointer_field().get_as::<::capnp::struct_list::Reader<'_,test_all_types::Owned>>(); + let result = root + .get_any_pointer_field() + .get_as::<::capnp::struct_list::Reader<'_, test_all_types::Owned>>(); assert!(result.is_err()); } #[test] fn empty_struct_list_amplification() { - use crate::test_capnp::{test_any_pointer, test_empty_struct, test_all_types}; + use crate::test_capnp::{test_all_types, test_any_pointer, test_empty_struct}; let mut message = message::Builder::new_default(); { let root = message.init_root::>(); - let _ : ::capnp::struct_list::Builder<'_, test_empty_struct::Owned> = + let _: ::capnp::struct_list::Builder<'_, test_empty_struct::Owned> = root.get_any_pointer_field().initn_as((1 << 29) - 1); } { @@ -1411,10 +1664,11 @@ mod tests { assert_eq!(segments[0].len(), 3 * 8); // 3 words let reader = - message::Reader::new(message::SegmentArray::new(&segments), - ReaderOptions::new()); + message::Reader::new(message::SegmentArray::new(&segments), ReaderOptions::new()); let root = reader.get_root::>().unwrap(); - let result = root.get_any_pointer_field().get_as::<::capnp::struct_list::Reader<'_, test_all_types::Owned>>(); + let result = root + .get_any_pointer_field() + .get_as::<::capnp::struct_list::Reader<'_, test_all_types::Owned>>(); assert!(result.is_err()); } @@ -1427,18 +1681,22 @@ mod tests { fn total_size_struct_list_amplification() { use crate::test_capnp::test_any_pointer; - let words: &[capnp::Word] = - &[capnp::word(0,0,0,0, 0,0,1,0), // struct, one pointers - capnp::word(1,0,0,0, 0xf,0,0,0), // list, inline composite, one word - capnp::word(0,0x80,0xc2,0xff, 0,0,0,0), // large struct, but zero of them - capnp::word(0,0,0x20,0, 0,0,0x22,0), - ]; + let words: &[capnp::Word] = &[ + capnp::word(0, 0, 0, 0, 0, 0, 1, 0), // struct, one pointers + capnp::word(1, 0, 0, 0, 0xf, 0, 0, 0), // list, inline composite, one word + capnp::word(0, 0x80, 0xc2, 0xff, 0, 0, 0, 0), // large struct, but zero of them + capnp::word(0, 0, 0x20, 0, 0, 0, 0x22, 0), + ]; let segment_array = &[capnp::Word::words_to_bytes(words)]; - let message_reader = - message::Reader::new(message::SegmentArray::new(segment_array), ReaderOptions::new()); + let message_reader = message::Reader::new( + message::SegmentArray::new(segment_array), + ReaderOptions::new(), + ); - let reader = message_reader.get_root::>().unwrap(); + let reader = message_reader + .get_root::>() + .unwrap(); reader.total_size().unwrap(); let mut builder = ::capnp::message::Builder::new_default(); @@ -1447,13 +1705,16 @@ mod tests { #[test] fn null_struct_fields() { - use crate::test_capnp::{test_all_types}; + use crate::test_capnp::test_all_types; let mut message = message::Builder::new_default(); { - let mut test = message.init_root::>(); - test.set_text_field("Hello"); + let mut test = message.init_root::>(); + test.set_text_field("Hello"); } - let reader = message.get_root::>().unwrap().into_reader(); + let reader = message + .get_root::>() + .unwrap() + .into_reader(); assert_eq!(reader.get_text_field().unwrap(), "Hello"); assert_eq!(reader.has_struct_field(), false); let nested = reader.get_struct_field().unwrap(); @@ -1500,16 +1761,15 @@ mod tests { #[test] fn get_raw_struct_data() { - use capnp::traits::HasStructSize; use crate::test_capnp::test_all_types; + use capnp::traits::HasStructSize; let mut message = message::Builder::new_default(); let mut root: test_all_types::Builder<'_> = message.init_root(); root.set_int8_field(3); root.set_int16_field(0x0abb); let struct_size = as HasStructSize>::STRUCT_SIZE; { - let raw_bytes = - ::capnp::raw::get_struct_data_section(root.reborrow().into_reader()); + let raw_bytes = ::capnp::raw::get_struct_data_section(root.reborrow().into_reader()); assert_eq!(raw_bytes.len(), (struct_size.data * 8) as usize); assert_eq!(raw_bytes[0], 0); // boolField assert_eq!(raw_bytes[1], 3); // int8Field @@ -1532,15 +1792,18 @@ mod tests { uint16_list.set(4, 14); assert_eq!( ::capnp::raw::get_list_element_size(uint16_list.reborrow().into_reader()), - ::capnp::private::layout::ElementSize::TwoBytes); + ::capnp::private::layout::ElementSize::TwoBytes + ); assert_eq!( ::capnp::raw::get_list_step_size_in_bits(uint16_list.reborrow().into_reader()), - 16); + 16 + ); assert_eq!( ::capnp::raw::get_list_bytes(uint16_list.reborrow().into_reader()), - &[10, 0, 11, 0, 12, 0, 13, 0, 14, 0]); + &[10, 0, 11, 0, 12, 0, 13, 0, 14, 0] + ); } } @@ -1581,7 +1844,9 @@ mod tests { t5.set_u_int32_field(5); } - let reader = message.get_root_as_reader::>().unwrap(); + let reader = message + .get_root_as_reader::>() + .unwrap(); let structs = reader.get_struct_list().unwrap(); let mut iter = structs.iter(); @@ -1625,8 +1890,9 @@ mod tests { renamed_struct::GoodFieldName(true) => (), _ => panic!("expected GoodFieldName(true)"), } - assert!(renamed_struct::RenamedEnum::Bar == root.get_another_good_field_name().unwrap()); - + assert!( + renamed_struct::RenamedEnum::Bar == root.get_another_good_field_name().unwrap() + ); match root.get_renamed_union().which().unwrap() { renamed_struct::renamed_union::Qux(_) => (), @@ -1643,9 +1909,7 @@ mod tests { init_test_message(typed_builder.init_root()); CheckTestMessage::check_test_message(typed_builder.get_root().unwrap()); - CheckTestMessage::check_test_message( - typed_builder.get_root_as_reader().unwrap(), - ); + CheckTestMessage::check_test_message(typed_builder.get_root_as_reader().unwrap()); let mut buffer = vec![]; capnp::serialize_packed::write_message(&mut buffer, typed_builder.borrow_inner()).unwrap(); @@ -1664,15 +1928,16 @@ mod tests { init_test_message(typed_builder.init_root()); CheckTestMessage::check_test_message(typed_builder.get_root().unwrap()); - CheckTestMessage::check_test_message( - typed_builder.get_root_as_reader().unwrap(), - ); + CheckTestMessage::check_test_message(typed_builder.get_root_as_reader().unwrap()); let mut buffer = vec![]; capnp::serialize::write_message(&mut buffer, typed_builder.borrow_inner()).unwrap(); - let reader = - capnp::serialize::read_message_from_flat_slice(&mut buffer.as_slice(), ReaderOptions::new()).unwrap(); + let reader = capnp::serialize::read_message_from_flat_slice( + &mut buffer.as_slice(), + ReaderOptions::new(), + ) + .unwrap(); let message_reader = TypedReader::<_, test_all_types::Owned>::new(reader); CheckTestMessage::check_test_message(message_reader.get().unwrap()); } @@ -1685,30 +1950,33 @@ mod tests { init_test_message(typed_builder.init_root()); CheckTestMessage::check_test_message(typed_builder.get_root().unwrap()); - CheckTestMessage::check_test_message( - typed_builder.get_root_as_reader().unwrap(), - ); + CheckTestMessage::check_test_message(typed_builder.get_root_as_reader().unwrap()); let mut buffer = vec![]; capnp::serialize::write_message(&mut buffer, typed_builder.borrow_inner()).unwrap(); - let reader = - capnp::serialize::read_message_from_flat_slice_no_alloc(&mut buffer.as_slice(), ReaderOptions::new()).unwrap(); + let reader = capnp::serialize::read_message_from_flat_slice_no_alloc( + &mut buffer.as_slice(), + ReaderOptions::new(), + ) + .unwrap(); let message_reader = TypedReader::<_, test_all_types::Owned>::new(reader); CheckTestMessage::check_test_message(message_reader.get().unwrap()); } #[test] fn test_raw_code_generator_request_path() { - use std::fs; use capnp::serialize; + use std::fs; let raw_code_gen_request = fs::read( std::env::var("OUT_DIR").expect("OUT_DIR env var is not set") - + "/raw_code_gen_request.bin" - ).expect("Failed to open raw code gen request file"); + + "/raw_code_gen_request.bin", + ) + .expect("Failed to open raw code gen request file"); - let reader = serialize::read_message(raw_code_gen_request.as_slice(), ReaderOptions::new()).unwrap(); + let reader = + serialize::read_message(raw_code_gen_request.as_slice(), ReaderOptions::new()).unwrap(); let generator_context = capnpc::codegen::GeneratorContext::new(&reader).unwrap(); assert!(generator_context.node_map.len() > 0); assert!(generator_context.scope_map.len() > 0); diff --git a/capnpc/test/test_util.rs b/capnpc/test/test_util.rs index 4c284b03c..607b8fc77 100644 --- a/capnpc/test/test_util.rs +++ b/capnpc/test/test_util.rs @@ -19,7 +19,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - use crate::test_capnp::{test_all_types, test_defaults, TestEnum}; pub fn init_test_message(mut builder: test_all_types::Builder<'_>) { @@ -56,7 +55,9 @@ pub fn init_test_message(mut builder: test_all_types::Builder<'_>) { { let mut sub_sub_builder = sub_builder.reborrow().init_struct_field(); sub_sub_builder.set_text_field("nested"); - sub_sub_builder.init_struct_field().set_text_field("really nested"); + sub_sub_builder + .init_struct_field() + .set_text_field("really nested"); } sub_builder.set_enum_field(TestEnum::Baz); @@ -109,9 +110,18 @@ pub fn init_test_message(mut builder: test_all_types::Builder<'_>) { // ... { let mut struct_list = sub_builder.reborrow().init_struct_list(3); - struct_list.reborrow().get(0).set_text_field("x structlist 1"); - struct_list.reborrow().get(1).set_text_field("x structlist 2"); - struct_list.reborrow().get(2).set_text_field("x structlist 3"); + struct_list + .reborrow() + .get(0) + .set_text_field("x structlist 1"); + struct_list + .reborrow() + .get(1) + .set_text_field("x structlist 2"); + struct_list + .reborrow() + .get(2) + .set_text_field("x structlist 3"); } let mut enum_list = sub_builder.reborrow().init_enum_list(3); diff --git a/example/addressbook/addressbook.rs b/example/addressbook/addressbook.rs index 9ca713302..9fa6159b7 100644 --- a/example/addressbook/addressbook.rs +++ b/example/addressbook/addressbook.rs @@ -20,7 +20,7 @@ // THE SOFTWARE. pub mod addressbook_capnp { - include!(concat!(env!("OUT_DIR"), "/addressbook_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/addressbook_capnp.rs")); } pub mod addressbook { @@ -42,7 +42,10 @@ pub mod addressbook { { let mut alice_phones = alice.reborrow().init_phones(1); alice_phones.reborrow().get(0).set_number("555-1212"); - alice_phones.reborrow().get(0).set_type(person::phone_number::Type::Mobile); + alice_phones + .reborrow() + .get(0) + .set_type(person::phone_number::Type::Mobile); } alice.get_employment().set_school("MIT"); } @@ -55,9 +58,15 @@ pub mod addressbook { { let mut bob_phones = bob.reborrow().init_phones(2); bob_phones.reborrow().get(0).set_number("555-4567"); - bob_phones.reborrow().get(0).set_type(person::phone_number::Type::Home); + bob_phones + .reborrow() + .get(0) + .set_type(person::phone_number::Type::Home); bob_phones.reborrow().get(1).set_number("555-7654"); - bob_phones.reborrow().get(1).set_type(person::phone_number::Type::Work); + bob_phones + .reborrow() + .get(1) + .set_type(person::phone_number::Type::Work); } bob.get_employment().set_unemployed(()); } @@ -68,8 +77,10 @@ pub mod addressbook { pub fn print_address_book() -> ::capnp::Result<()> { let stdin = ::std::io::stdin(); - let message_reader = serialize_packed::read_message(&mut stdin.lock(), - ::capnp::message::ReaderOptions::new())?; + let message_reader = serialize_packed::read_message( + &mut stdin.lock(), + ::capnp::message::ReaderOptions::new(), + )?; let address_book = message_reader.get_root::()?; for person in address_book.get_people()?.iter() { @@ -96,7 +107,7 @@ pub mod addressbook { Ok(person::employment::SelfEmployed(())) => { println!(" self-employed"); } - Err(::capnp::NotInSchema(_)) => { } + Err(::capnp::NotInSchema(_)) => {} } } Ok(()) @@ -104,16 +115,16 @@ pub mod addressbook { } pub fn main() { - - let args : Vec = ::std::env::args().collect(); + let args: Vec = ::std::env::args().collect(); if args.len() < 2 { println!("usage: $ {} [write | read]", args[0]); } else { match &*args[1] { "write" => addressbook::write_address_book().unwrap(), - "read" => addressbook::print_address_book().unwrap(), - _ => {println!("unrecognized argument") } + "read" => addressbook::print_address_book().unwrap(), + _ => { + println!("unrecognized argument") + } } } - } diff --git a/example/addressbook_send/addressbook_send.rs b/example/addressbook_send/addressbook_send.rs index 7f822b56b..adc0bb3b1 100644 --- a/example/addressbook_send/addressbook_send.rs +++ b/example/addressbook_send/addressbook_send.rs @@ -23,7 +23,7 @@ extern crate capnp; extern crate core; pub mod addressbook_capnp { - include!(concat!(env!("OUT_DIR"), "/addressbook_capnp.rs")); + include!(concat!(env!("OUT_DIR"), "/addressbook_capnp.rs")); } use capnp::message::{Builder, HeapAllocator, TypedReader}; @@ -32,7 +32,7 @@ use std::thread; pub mod addressbook { use addressbook_capnp::{address_book, person}; - use capnp::message::{Builder, HeapAllocator, TypedReader, TypedBuilder}; + use capnp::message::{Builder, HeapAllocator, TypedBuilder, TypedReader}; pub fn build_address_book() -> TypedReader, address_book::Owned> { let mut message = TypedBuilder::::new_default(); @@ -49,7 +49,10 @@ pub mod addressbook { { let mut alice_phones = alice.reborrow().init_phones(1); alice_phones.reborrow().get(0).set_number("555-1212"); - alice_phones.reborrow().get(0).set_type(person::phone_number::Type::Mobile); + alice_phones + .reborrow() + .get(0) + .set_type(person::phone_number::Type::Mobile); } alice.get_employment().set_school("MIT"); } @@ -62,9 +65,15 @@ pub mod addressbook { { let mut bob_phones = bob.reborrow().init_phones(2); bob_phones.reborrow().get(0).set_number("555-4567"); - bob_phones.reborrow().get(0).set_type(person::phone_number::Type::Home); + bob_phones + .reborrow() + .get(0) + .set_type(person::phone_number::Type::Home); bob_phones.reborrow().get(1).set_number("555-7654"); - bob_phones.reborrow().get(1).set_type(person::phone_number::Type::Work); + bob_phones + .reborrow() + .get(1) + .set_type(person::phone_number::Type::Work); } bob.get_employment().set_unemployed(()); } @@ -84,10 +93,11 @@ pub mod addressbook { } pub fn main() { - let book = addressbook::build_address_book(); - let (tx_book, rx_book) = mpsc::channel::, addressbook_capnp::address_book::Owned>>(); + let (tx_book, rx_book) = mpsc::channel::< + TypedReader, addressbook_capnp::address_book::Owned>, + >(); let (tx_id, rx_id) = mpsc::channel::(); thread::spawn(move || {