Skip to content

Commit

Permalink
Add cfg(feature=alloc) guards
Browse files Browse the repository at this point in the history
This allows us to compile capnproto in no-alloc environments.
  • Loading branch information
ariel-miculas committed Jun 29, 2023
1 parent 5414689 commit 873a1b7
Show file tree
Hide file tree
Showing 29 changed files with 302 additions and 32 deletions.
18 changes: 16 additions & 2 deletions capnp/src/any_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@

//! Untyped pointer that can be cast to any struct, list, or capability type.
use alloc::boxed::Box;
use alloc::vec::Vec;
#[cfg(feature = "alloc")]
use alloc::{boxed::Box, vec::Vec};

#[cfg(feature = "alloc")]
use crate::capability::FromClientHook;
#[cfg(feature = "alloc")]
use crate::private::capability::{ClientHook, PipelineHook, PipelineOp};
use crate::private::layout::{PointerBuilder, PointerReader};
use crate::traits::{FromPointerBuilder, FromPointerReader, SetPointerBuilder};
Expand All @@ -44,6 +46,7 @@ impl crate::introspect::Introspect for Owned {
}
}

#[cfg(feature = "alloc")]
impl crate::traits::Pipelined for Owned {
type Pipeline = Pipeline;
}
Expand Down Expand Up @@ -73,12 +76,14 @@ impl<'a> Reader<'a> {
FromPointerReader::get_from_pointer(&self.reader, None)
}

#[cfg(feature = "alloc")]
pub fn get_as_capability<T: FromClientHook>(&self) -> Result<T> {
Ok(FromClientHook::new(self.reader.get_capability()?))
}

//# Used by RPC system to implement pipelining. Applications
//# generally shouldn't use this directly.
#[cfg(feature = "alloc")]
pub fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Result<Box<dyn ClientHook>> {
let mut pointer = self.reader;

Expand Down Expand Up @@ -117,6 +122,7 @@ impl<'a> crate::traits::SetPointerBuilder for Reader<'a> {
}
}

#[cfg(feature = "alloc")]
impl<'a> crate::traits::Imbue<'a> for Reader<'a> {
fn imbue(&mut self, cap_table: &'a crate::private::layout::CapTable) {
self.reader
Expand Down Expand Up @@ -165,6 +171,7 @@ impl<'a> Builder<'a> {
}

// XXX value should be a user client.
#[cfg(feature = "alloc")]
pub fn set_as_capability(&mut self, value: Box<dyn ClientHook>) {
self.builder.set_capability(value);
}
Expand Down Expand Up @@ -199,20 +206,23 @@ impl<'a> FromPointerBuilder<'a> for Builder<'a> {
}
}

#[cfg(feature = "alloc")]
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));
}
}

#[cfg(feature = "alloc")]
pub struct Pipeline {
// XXX this should not be public
pub hook: Box<dyn PipelineHook>,

ops: Vec<PipelineOp>,
}

#[cfg(feature = "alloc")]
impl Pipeline {
pub fn new(hook: Box<dyn PipelineHook>) -> Self {
Self {
Expand Down Expand Up @@ -245,24 +255,28 @@ impl Pipeline {
}
}

#[cfg(feature = "alloc")]
impl crate::capability::FromTypelessPipeline for Pipeline {
fn new(typeless: Pipeline) -> Self {
typeless
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
fn from(a: Reader<'a>) -> crate::dynamic_value::Reader<'a> {
crate::dynamic_value::Reader::AnyPointer(a)
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Builder<'a>> for crate::dynamic_value::Builder<'a> {
fn from(a: Builder<'a>) -> crate::dynamic_value::Builder<'a> {
crate::dynamic_value::Builder::AnyPointer(a)
}
}

#[cfg(feature = "alloc")]
#[test]
fn init_clears_value() {
let mut message = crate::message::Builder::new_default();
Expand Down
2 changes: 2 additions & 0 deletions capnp/src/any_pointer_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ impl<'a> core::iter::IntoIterator for Reader<'a> {
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
fn from(t: Reader<'a>) -> crate::dynamic_value::Reader<'a> {
crate::dynamic_value::Reader::List(crate::dynamic_list::Reader::new(
Expand All @@ -198,6 +199,7 @@ impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Builder<'a>> for crate::dynamic_value::Builder<'a> {
fn from(t: Builder<'a>) -> crate::dynamic_value::Builder<'a> {
crate::dynamic_value::Builder::List(crate::dynamic_list::Builder::new(
Expand Down
1 change: 1 addition & 0 deletions capnp/src/capability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//! Hooks for for the RPC system.
//!
//! Roughly corresponds to capability.h in the C++ implementation.
#![cfg(feature = "alloc")]

use alloc::boxed::Box;
use core::future::Future;
Expand Down
1 change: 1 addition & 0 deletions capnp/src/capability_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// THE SOFTWARE.

//! List of capabilities.
#![cfg(feature = "alloc")]

use alloc::boxed::Box;
use core::marker::PhantomData;
Expand Down
2 changes: 2 additions & 0 deletions capnp/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,14 @@ impl<'a> crate::traits::SetPointerBuilder for Reader<'a> {
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
fn from(d: Reader<'a>) -> crate::dynamic_value::Reader<'a> {
crate::dynamic_value::Reader::Data(d)
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Builder<'a>> for crate::dynamic_value::Builder<'a> {
fn from(d: Builder<'a>) -> crate::dynamic_value::Builder<'a> {
crate::dynamic_value::Builder::Data(d)
Expand Down
2 changes: 2 additions & 0 deletions capnp/src/data_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ impl<'a> ::core::iter::IntoIterator for Reader<'a> {
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
fn from(t: Reader<'a>) -> crate::dynamic_value::Reader<'a> {
crate::dynamic_value::Reader::List(crate::dynamic_list::Reader {
Expand All @@ -208,6 +209,7 @@ impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
}
}

#[cfg(feature = "alloc")]
impl<'a> From<Builder<'a>> for crate::dynamic_value::Builder<'a> {
fn from(t: Builder<'a>) -> crate::dynamic_value::Builder<'a> {
crate::dynamic_value::Builder::List(crate::dynamic_list::Builder {
Expand Down
1 change: 1 addition & 0 deletions capnp/src/dynamic_list.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Dynamically-typed lists.
#![cfg(feature = "alloc")]
use crate::dynamic_value;
use crate::introspect::{Type, TypeVariant};
use crate::private::layout::{self, PrimitiveElement};
Expand Down
1 change: 1 addition & 0 deletions capnp/src/dynamic_struct.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Dynamically-typed structs.
#![cfg(feature = "alloc")]
use crate::introspect::TypeVariant;
use crate::private::layout;
use crate::schema::{Field, StructSchema};
Expand Down
1 change: 1 addition & 0 deletions capnp/src/dynamic_value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Dynamically typed values.
#![cfg(feature = "alloc")]
use crate::introspect::{self, TypeVariant};
use crate::schema_capnp::value;
use crate::Result;
Expand Down
2 changes: 2 additions & 0 deletions capnp/src/enum_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ impl<'a, T: TryFrom<u16, Error = NotInSchema>> ::core::iter::IntoIterator for Re
}
}

#[cfg(feature = "alloc")]
impl<'a, T: TryFrom<u16, Error = NotInSchema> + crate::introspect::Introspect> From<Reader<'a, T>>
for crate::dynamic_value::Reader<'a>
{
Expand All @@ -225,6 +226,7 @@ impl<'a, T: TryFrom<u16, Error = NotInSchema> + crate::introspect::Introspect> F
}
}

#[cfg(feature = "alloc")]
impl<'a, T: TryFrom<u16, Error = NotInSchema> + crate::introspect::Introspect> From<Builder<'a, T>>
for crate::dynamic_value::Builder<'a>
{
Expand Down
2 changes: 2 additions & 0 deletions capnp/src/introspect.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Traits and types to support run-time type introspection, i.e. reflection.
#[cfg(feature = "alloc")]
use crate::private::layout::ElementSize;

/// A type that supports reflection. All types that can appear in a Cap'n Proto message
Expand Down Expand Up @@ -70,6 +71,7 @@ impl Type {

/// If this type T appears as List(T), then what is the expected
/// element size of the list?
#[cfg(feature = "alloc")]
pub(crate) fn expected_element_size(&self) -> ElementSize {
if self.list_count > 0 {
ElementSize::Pointer
Expand Down
1 change: 1 addition & 0 deletions capnp/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ mod no_std_impls {
}
}

#[cfg(feature = "alloc")]
impl Write for alloc::vec::Vec<u8> {
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.extend_from_slice(buf);
Expand Down
8 changes: 8 additions & 0 deletions capnp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
#![cfg_attr(feature = "rpc_try", feature(try_trait_v2))]
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(feature = "alloc")]
#[macro_use]
extern crate alloc;

/// Code generated from
/// [schema.capnp](https://github.com/capnproto/capnproto/blob/master/c%2B%2B/src/capnp/schema.capnp).
#[cfg(feature = "alloc")]
pub mod schema_capnp;

pub mod any_pointer;
Expand Down Expand Up @@ -65,6 +67,7 @@ pub mod traits;

#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;

///
Expand All @@ -81,6 +84,7 @@ pub struct Word {
///
/// Constructs a word with the given bytes.
///
#[allow(clippy::too_many_arguments)]
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],
Expand All @@ -89,6 +93,7 @@ pub const fn word(b0: u8, b1: u8, b2: u8, b3: u8, b4: u8, b5: u8, b6: u8, b7: u8

impl Word {
/// Allocates a vec of `length` words, all set to zero.
#[cfg(feature = "alloc")]
pub fn allocate_zeroed_vec(length: usize) -> Vec<Self> {
vec![word(0, 0, 0, 0, 0, 0, 0, 0); length]
}
Expand Down Expand Up @@ -589,11 +594,13 @@ impl ::std::error::Error for Error {

/// Helper struct that allows `MessageBuilder::get_segments_for_output()` to avoid heap allocations
/// in the single-segment case.
#[cfg(feature = "alloc")]
pub enum OutputSegments<'a> {
SingleSegment([&'a [u8]; 1]),
MultiSegment(Vec<&'a [u8]>),
}

#[cfg(feature = "alloc")]
impl<'a> core::ops::Deref for OutputSegments<'a> {
type Target = [&'a [u8]];
fn deref(&self) -> &[&'a [u8]] {
Expand All @@ -604,6 +611,7 @@ impl<'a> core::ops::Deref for OutputSegments<'a> {
}
}

#[cfg(feature = "alloc")]
impl<'s> message::ReaderSegments for OutputSegments<'s> {
fn get_segment(&self, id: u32) -> Option<&[u8]> {
match self {
Expand Down
2 changes: 2 additions & 0 deletions capnp/src/list_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ where
}
}

#[cfg(feature = "alloc")]
impl<'a, T: crate::traits::Owned> From<Reader<'a, T>> for crate::dynamic_value::Reader<'a> {
fn from(t: Reader<'a, T>) -> crate::dynamic_value::Reader<'a> {
crate::dynamic_value::Reader::List(crate::dynamic_list::Reader::new(
Expand All @@ -289,6 +290,7 @@ impl<'a, T: crate::traits::Owned> From<Reader<'a, T>> for crate::dynamic_value::
}
}

#[cfg(feature = "alloc")]
impl<'a, T: crate::traits::Owned> From<Builder<'a, T>> for crate::dynamic_value::Builder<'a> {
fn from(t: Builder<'a, T>) -> crate::dynamic_value::Builder<'a> {
crate::dynamic_value::Builder::List(crate::dynamic_list::Builder::new(
Expand Down
Loading

0 comments on commit 873a1b7

Please sign in to comment.