Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for no-std #184

Merged
merged 1 commit into from
May 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ sudo: false
language: rust
matrix:
include:
- rust: stable
#- rust: stable
- rust: beta
- rust: nightly
- rust: 1.40.0
#- rust: 1.44.0
env:
global:
- export PATH="$PATH:$HOME/bin"
Expand All @@ -26,6 +26,9 @@ install:
- cd ../

script:
- cd capnp
- cargo test --no-default-features
- cd ../
- cargo build --all
- cargo test --all
- ./target/debug/addressbook write | ./target/debug/addressbook read
Expand Down
4 changes: 4 additions & 0 deletions capnp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ quickcheck = { version = "0.9", optional = true }
quickcheck = "0.9"

[features]
default = ["std"]

rpc_try = []

# If enabled, relaxes alignment requirements on segments.
# This has a performance cost on some targets (e.g. ARMv6).
unaligned = []

std = []

3 changes: 3 additions & 0 deletions capnp/src/any_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

//! Dynamically typed value.
use alloc::boxed::Box;
use alloc::vec::Vec;

use crate::capability::FromClientHook;
use crate::private::capability::{ClientHook, PipelineHook, PipelineOp};
use crate::private::layout::{PointerReader, PointerBuilder};
Expand Down
2 changes: 1 addition & 1 deletion capnp/src/any_pointer_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ impl <'a> crate::traits::SetPointerBuilder<Builder<'a>> for Reader<'a> {
}
}

impl <'a> ::std::iter::IntoIterator for Reader<'a> {
impl <'a> core::iter::IntoIterator for Reader<'a> {
type Item = Result<crate::any_pointer::Reader<'a>>;
type IntoIter = ListIter<Reader<'a>, Self::Item>;

Expand Down
29 changes: 14 additions & 15 deletions capnp/src/capability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,18 @@
//!
//! Roughly corresponds to capability.h in the C++ implementation.
use alloc::boxed::Box;
use core::future::{Future};
use core::pin::{Pin};
use core::marker::{PhantomData, Unpin};
use core::task::Poll;
#[cfg(feature = "rpc_try")]
use core::ops::Try;

use crate::{any_pointer, Error, MessageSize};
use crate::traits::{Pipelined, Owned};
use crate::private::capability::{ClientHook, ParamsHook, RequestHook, ResponseHook, ResultsHook};

use std::future::{Future};
use std::pin::{Pin};
use std::marker::Unpin;
use std::task::Poll;
#[cfg(feature = "rpc_try")]
use std::ops::Try;

use std::marker::PhantomData;

/// 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.
#[must_use = "futures do nothing unless polled"]
Expand All @@ -45,7 +44,7 @@ pub struct Promise<T, E> {

enum PromiseInner<T, E> {
Immediate(Result<T,E>),
Deferred(Pin<Box<dyn Future<Output=std::result::Result<T,E>> + 'static>>),
Deferred(Pin<Box<dyn Future<Output=core::result::Result<T,E>> + 'static>>),
Empty,
}

Expand All @@ -62,21 +61,21 @@ impl <T, E> Promise<T, E> {
}

pub fn from_future<F>(f: F) -> Promise<T, E>
where F: Future<Output=std::result::Result<T,E>> + 'static
where F: Future<Output=core::result::Result<T,E>> + 'static
{
Promise { inner: PromiseInner::Deferred(Box::pin(f)) }
}
}

impl <T, E> Future for Promise<T, E>
{
type Output = std::result::Result<T,E>;
type Output = core::result::Result<T,E>;

fn poll(self: Pin<&mut Self>, cx: &mut ::std::task::Context) -> Poll<Self::Output> {
fn poll(self: Pin<&mut Self>, cx: &mut ::core::task::Context) -> Poll<Self::Output> {
match self.get_mut().inner {
PromiseInner::Empty => panic!("Promise polled after done."),
ref mut imm @ PromiseInner::Immediate(_) => {
match std::mem::replace(imm, PromiseInner::Empty) {
match core::mem::replace(imm, PromiseInner::Empty) {
PromiseInner::Immediate(r) => Poll::Ready(r),
_ => unreachable!(),
}
Expand Down Expand Up @@ -254,7 +253,7 @@ pub trait Server {
/// Trait to track the relationship between generated Server traits and Client structs.
pub trait FromServer<S> : FromClientHook {
// Implemented by the generated ServerDispatch struct.
type Dispatch: Server + 'static + std::ops::DerefMut<Target=S>;
type Dispatch: Server + 'static + core::ops::DerefMut<Target=S>;

fn from_server(s: S) -> Self::Dispatch;
}
5 changes: 3 additions & 2 deletions capnp/src/capability_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@

//! List of capabilities.
use std::marker::PhantomData;
use alloc::boxed::Box;
use core::marker::PhantomData;

use crate::capability::{FromClientHook};
use crate::private::capability::ClientHook;
Expand Down Expand Up @@ -152,7 +153,7 @@ impl <'a, T> crate::traits::SetPointerBuilder<Builder<'a, T>> for Reader<'a, T>
}
}

impl <'a, T> ::std::iter::IntoIterator for Reader<'a, T>
impl <'a, T> ::core::iter::IntoIterator for Reader<'a, T>
where T: FromClientHook
{
type Item = Result<T>;
Expand Down
2 changes: 1 addition & 1 deletion capnp/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
//! `constant::Reader` does not do bounds-checking, so it is unsafe to
//! manually construct one of these.
use std::marker::PhantomData;
use core::marker::PhantomData;

use crate::any_pointer;
use crate::private::layout::PointerReader;
Expand Down
4 changes: 2 additions & 2 deletions capnp/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<'a> crate::traits::Owned<'a> for Owned {
pub type Reader<'a> = &'a [u8];

pub fn new_reader<'a>(p : *const u8, len : u32) -> Reader<'a> {
unsafe { ::std::slice::from_raw_parts(p, len as usize) }
unsafe { ::core::slice::from_raw_parts(p, len as usize) }
}

impl <'a> crate::traits::FromPointerReader<'a> for Reader<'a> {
Expand All @@ -47,7 +47,7 @@ impl <'a> crate::traits::FromPointerReader<'a> for Reader<'a> {
pub type Builder<'a> = &'a mut [u8];

pub fn new_builder<'a>(p : *mut u8, len : u32) -> Builder<'a> {
unsafe { ::std::slice::from_raw_parts_mut(p, len as usize) }
unsafe { ::core::slice::from_raw_parts_mut(p, len as usize) }
}

impl <'a> crate::traits::FromPointerBuilder<'a> for Builder<'a> {
Expand Down
2 changes: 1 addition & 1 deletion capnp/src/data_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl <'a> crate::traits::SetPointerBuilder<Builder<'a>> for Reader<'a> {
}
}

impl <'a> ::std::iter::IntoIterator for Reader<'a> {
impl <'a> ::core::iter::IntoIterator for Reader<'a> {
type Item = Result<crate::data::Reader<'a>>;
type IntoIter = ListIter<Reader<'a>, Self::Item>;

Expand Down
16 changes: 8 additions & 8 deletions capnp/src/enum_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::private::layout::{ListReader, ListBuilder, PointerReader, PointerBuil
TwoBytes, PrimitiveElement};
use crate::{NotInSchema, Result};

use std::marker::PhantomData;
use core::marker::PhantomData;

#[derive(Clone, Copy)]
pub struct Owned<T> {
Expand All @@ -52,7 +52,7 @@ impl <'a, T: FromU16> Reader<'a, T> {

pub fn len(&self) -> u32 { self.reader.len() }

pub fn iter(self) -> ListIter<Reader<'a, T>, ::std::result::Result<T, NotInSchema>>{
pub fn iter(self) -> ListIter<Reader<'a, T>, ::core::result::Result<T, NotInSchema>>{
let l = self.len();
ListIter::new(self, l)
}
Expand All @@ -65,14 +65,14 @@ impl <'a, T : FromU16> FromPointerReader<'a> for Reader<'a, T> {
}
}

impl <'a, T: FromU16> IndexMove<u32, ::std::result::Result<T, NotInSchema>> for Reader<'a, T>{
fn index_move(&self, index: u32) -> ::std::result::Result<T, NotInSchema> {
impl <'a, T: FromU16> IndexMove<u32, ::core::result::Result<T, NotInSchema>> for Reader<'a, T>{
fn index_move(&self, index: u32) -> ::core::result::Result<T, NotInSchema> {
self.get(index)
}
}

impl <'a, T : FromU16> Reader<'a, T> {
pub fn get(&self, index: u32) -> ::std::result::Result<T, NotInSchema> {
pub fn get(&self, index: u32) -> ::core::result::Result<T, NotInSchema> {
assert!(index < self.len());
let result: u16 = PrimitiveElement::get(&self.reader, index);
FromU16::from_u16(result)
Expand Down Expand Up @@ -119,7 +119,7 @@ impl <'a, T : FromU16> FromPointerBuilder<'a> for Builder<'a, T> {
}

impl <'a, T : ToU16 + FromU16> Builder<'a, T> {
pub fn get(&self, index: u32) -> ::std::result::Result<T, NotInSchema> {
pub fn get(&self, index: u32) -> ::core::result::Result<T, NotInSchema> {
assert!(index < self.len());
let result: u16 = PrimitiveElement::get_from_builder(&self.builder, index);
FromU16::from_u16(result)
Expand All @@ -138,8 +138,8 @@ impl <'a, T> crate::traits::SetPointerBuilder<Builder<'a, T>> for Reader<'a, T>
}
}

impl <'a, T: FromU16> ::std::iter::IntoIterator for Reader<'a, T> {
type Item = ::std::result::Result<T, NotInSchema>;
impl <'a, T: FromU16> ::core::iter::IntoIterator for Reader<'a, T> {
type Item = ::core::result::Result<T, NotInSchema>;
type IntoIter = ListIter<Reader<'a, T>, Self::Item>;

fn into_iter(self) -> Self::IntoIter {
Expand Down
115 changes: 115 additions & 0 deletions capnp/src/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//! Custom I/O traits that roughly mirror `std::io::{Read, BufRead, Write}`.
//! This extra layer of indirection enables support of no-std environments.
use crate::Result;

pub trait Read {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()>;
}

pub trait BufRead : Read {
fn fill_buf(&mut self) -> Result<&[u8]>;
fn consume(&mut self, amt: usize);
}

pub trait Write {
fn write_all(&mut self, buf: &[u8]) -> Result<()>;
}

#[cfg(feature="std")]
mod std_impls {
use crate::{Result};
use crate::io::{Read, BufRead, Write};

impl <R> Read for R where R: std::io::Read {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}

impl <R> BufRead for R where R: std::io::BufRead {
fn fill_buf(&mut self) -> Result<&[u8]> {
Ok(std::io::BufRead::fill_buf(self)?)
}
fn consume(&mut self, amt: usize) {
std::io::BufRead::consume(self, amt)
}
}

impl <W> Write for W where W: std::io::Write {
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
std::io::Write::write_all(self, buf)?;
Ok(())
}
}
}

#[cfg(not(feature="std"))]
mod no_std_impls {
use alloc::string::ToString;
use crate::{Error, Result};
use crate::io::{Read, BufRead, Write};

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()));
}
let amt = buf.len();
let (a, b) = core::mem::replace(self, &mut []).split_at_mut(amt);
a.copy_from_slice(buf);
*self = b;
Ok(())
}
}

impl Write for alloc::vec::Vec<u8> {
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.extend_from_slice(buf);
Ok(())
}
}

impl <W: ?Sized> 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] {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
if buf.len() > self.len() {
return Err(Error::failed("buffer is not large enough".to_string()));
}
let (a, b) = self.split_at(buf.len());
buf.copy_from_slice(a);
*self = b;
Ok(())
}
}

impl <R: ?Sized> Read for &mut R where R: Read {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
(**self).read_exact(buf)
}
}

impl <'a> BufRead for &'a [u8] {
fn fill_buf(&mut self) -> Result<&[u8]> {
Ok(*self)
}
fn consume(&mut self, amt: usize) {
*self = &self[amt..]
}
}

impl <R: ?Sized> BufRead for &mut R where R: BufRead {
fn fill_buf(&mut self) -> Result<&[u8]> {
(**self).fill_buf()
}
fn consume(&mut self, amt: usize) {
(**self).consume(amt)
}
}
}
Loading