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

feat: blockwise transfer #274

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
38 changes: 27 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions toad/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,19 @@ test = []
docs = []

[dependencies]
toad-array = {version = "0.2.3", default_features = false}
toad-array = {version = "0.8.0", default_features = false}
toad-map = {version = "0.2.3", default_features = false}
toad-len = {version = "0.1.3", default_features = false}
toad-hash = {version = "0.3.0", default_features = false}
toad-writable = {version = "0.1.1", default_features = false}
toad-stem = {version = "0.1.0", default_features = false}
toad-string = {version = "0.2.0", default_features = false}
toad-msg = "0.18.1"
toad-msg = "0.19.0"
toad-macros = "0.2.0"
log = "0.4"
tinyvec = { version = "1.5", default_features = false, features = ["rustc_1_55"] }
tinyvec = { version = "1.5", default_features = false, features = [
"rustc_1_55"
] }
no-std-net = "0.6"
embedded-time = "0.12"
nb = "1"
Expand All @@ -65,6 +67,6 @@ serde-json-core = { version = "0.5.0", optional = true }
simple_logger = "2"
lazycell = "1.3.0"
paste = "1.0.9"
serde = {version = "1.0", features = ["derive"]}
serde = { version = "1.0", features = ["derive"] }
serde-json-core = { version = "0.5.0" }
serde_json = { version = "1.0" }
2 changes: 0 additions & 2 deletions toad/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![allow(dead_code)]

use embedded_time::duration::Milliseconds;

use crate::retry::{Attempts, Strategy};
Expand Down
9 changes: 7 additions & 2 deletions toad/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,21 @@ pub mod multicast {
}

macro_rules! code {
(rfc7252($section:literal) $name:ident = $c:literal.$d:literal) => {
(rfc7252($section:literal) $name:ident = $c:literal*$d:literal) => {
#[doc = toad_macros::rfc_7252_doc!($section)]
#[allow(clippy::zero_prefixed_literal)]
pub const $name: toad_msg::Code = toad_msg::Code::new($c, $d);
};
(rfc7252($section:literal) $name:ident = $newtype:tt($c:literal.$d:literal)) => {
(rfc7252($section:literal) $name:ident = $newtype:tt($c:literal*$d:literal)) => {
#[doc = toad_macros::rfc_7252_doc!($section)]
#[allow(clippy::zero_prefixed_literal)]
pub const $name: $newtype = $newtype(toad_msg::Code::new($c, $d));
};
(#[doc = $docstr:expr] $name:ident = $c:literal*$d:literal) => {
#[doc = $docstr]
#[allow(clippy::zero_prefixed_literal)]
pub const $name: toad_msg::Code = toad_msg::Code::new($c, $d);
};
}

pub(crate) use code;
22 changes: 19 additions & 3 deletions toad/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use naan::prelude::MonadOnce;
use no_std_net::SocketAddr;
#[cfg(feature = "alloc")]
use std_alloc::vec::Vec;
use toad_array::{AppendCopy, Array};
use toad_array::{AppendCopy, Array, Indexed};

use crate::config::Config;
use crate::net::{Addrd, Socket};
Expand Down Expand Up @@ -232,11 +232,11 @@ pub trait Platform<Steps>
| Ok(()) => nb::block!(self.exec_1(&eff)).map_err(|e| {
let mut effs: <Self::Types as PlatformTypes>::Effects =
Default::default();
effs.push(eff);
effs.append(eff);
(effs, e)
}),
| Err((mut effs, e)) => {
effs.push(eff);
effs.append(eff);
Err((effs, e))
},
})
Expand Down Expand Up @@ -341,6 +341,22 @@ pub enum Effect<P>
Nop,
}

impl<P> Effect<P> where P: PlatformTypes
{
/// Is this [`Effect::Send`]?
pub fn is_send(&self) -> bool {
self.get_send().is_some()
}

/// If this is [`Effect::Send`], yields a reference to the message
pub fn get_send(&self) -> Option<&Addrd<self::toad_msg::Message<P>>> {
match self {
| Self::Send(r) => Some(r),
| _ => None,
}
}
}

impl<P> Default for Effect<P> where P: PlatformTypes
{
fn default() -> Self {
Expand Down
10 changes: 5 additions & 5 deletions toad/src/req/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ impl core::fmt::Display for Method {
}

impl Method {
code!(rfc7252("4.1") EMPTY = Method(0 . 00));
code!(rfc7252("5.8.1") GET = Method(0 . 01));
code!(rfc7252("5.8.2") POST = Method(0 . 02));
code!(rfc7252("5.8.3") PUT = Method(0 . 03));
code!(rfc7252("5.8.4") DELETE = Method(0 . 04));
code!(rfc7252("4.1") EMPTY = Method(0*00));
code!(rfc7252("5.8.1") GET = Method(0*01));
code!(rfc7252("5.8.2") POST = Method(0*02));
code!(rfc7252("5.8.3") PUT = Method(0*03));
code!(rfc7252("5.8.4") DELETE = Method(0*04));
}
64 changes: 43 additions & 21 deletions toad/src/resp/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,50 @@ pub use toad_msg::Code;
use crate::code;

// 2.xx
code!(rfc7252("5.9.1.1") CREATED = 2 . 01);
code!(rfc7252("5.9.1.2") DELETED = 2 . 02);
code!(rfc7252("5.9.1.3") VALID = 2 . 03);
code!(rfc7252("5.9.1.4") CHANGED = 2 . 04);
code!(rfc7252("5.9.1.5") CONTENT = 2 . 05);
code!(rfc7252("5.9.1.1") CREATED = 2*01);
code!(rfc7252("5.9.1.2") DELETED = 2*02);
code!(rfc7252("5.9.1.3") VALID = 2*03);
code!(rfc7252("5.9.1.4") CHANGED = 2*04);
code!(rfc7252("5.9.1.5") CONTENT = 2*05);
code!(
#[doc = concat!(
"## [2.31 Continue](https://www.rfc-editor.org/rfc/rfc7959#section-2.9.1)\n",
"This success status code indicates that the transfer of this\n",
"block of the request body was successful and that the server\n",
"encourages sending further blocks, but that a final outcome of the\n",
"whole block-wise request cannot yet be determined. No payload is\n",
"returned with this response code.",
)]
CONTINUE = 2 * 31
);

// 4.xx
code!(rfc7252("5.9.2.1") BAD_REQUEST = 4 . 00);
code!(rfc7252("5.9.2.2") UNAUTHORIZED = 4 . 01);
code!(rfc7252("5.9.2.3") BAD_OPTION = 4 . 02);
code!(rfc7252("5.9.2.4") FORBIDDEN = 4 . 03);
code!(rfc7252("5.9.2.5") NOT_FOUND = 4 . 04);
code!(rfc7252("5.9.2.6") METHOD_NOT_ALLOWED = 4 . 05);
code!(rfc7252("5.9.2.7") NOT_ACCEPTABLE = 4 . 06);
code!(rfc7252("5.9.2.8") PRECONDITION_FAILED = 4 . 12);
code!(rfc7252("5.9.2.9") REQUEST_ENTITY_TOO_LARGE = 4 . 13);
code!(rfc7252("5.9.2.10") UNSUPPORTED_CONTENT_FORMAT = 4 . 15);
code!(rfc7252("5.9.2.1") BAD_REQUEST = 4*00);
code!(rfc7252("5.9.2.2") UNAUTHORIZED = 4*01);
code!(rfc7252("5.9.2.3") BAD_OPTION = 4*02);
code!(rfc7252("5.9.2.4") FORBIDDEN = 4*03);
code!(rfc7252("5.9.2.5") NOT_FOUND = 4*04);
code!(rfc7252("5.9.2.6") METHOD_NOT_ALLOWED = 4*05);
code!(rfc7252("5.9.2.7") NOT_ACCEPTABLE = 4*06);
code!(
#[doc = concat!(
"## [4.08 Request Entity Incomplete](https://www.rfc-editor.org/rfc/rfc7959#section-2.9.2)\n",
"This client error status code indicates that the server has not\n",
"received the blocks of the request body that it needs to proceed.\n",
"The client has not sent all blocks, not sent them in the order\n",
"required by the server, or has sent them long enough ago that the\n",
"server has already discarded them.",
)]
REQUEST_ENTITY_INCOMPLETE = 4 * 08
);
code!(rfc7252("5.9.2.8") PRECONDITION_FAILED = 4*12);
code!(rfc7252("5.9.2.9") REQUEST_ENTITY_TOO_LARGE = 4*13);
code!(rfc7252("5.9.2.10") UNSUPPORTED_CONTENT_FORMAT = 4*15);

// 5.xx
code!(rfc7252("5.9.3.1") INTERNAL_SERVER_ERROR = 5 . 00);
code!(rfc7252("5.9.3.2") NOT_IMPLEMENTED = 5 . 01);
code!(rfc7252("5.9.3.3") BAD_GATEWAY = 5 . 02);
code!(rfc7252("5.9.3.4") SERVICE_UNAVAILABLE = 5 . 03);
code!(rfc7252("5.9.3.5") GATEWAY_TIMEOUT = 5 . 04);
code!(rfc7252("5.9.3.6") PROXYING_NOT_SUPPORTED = 5 . 05);
code!(rfc7252("5.9.3.1") INTERNAL_SERVER_ERROR = 5*00);
code!(rfc7252("5.9.3.2") NOT_IMPLEMENTED = 5*01);
code!(rfc7252("5.9.3.3") BAD_GATEWAY = 5*02);
code!(rfc7252("5.9.3.4") SERVICE_UNAVAILABLE = 5*03);
code!(rfc7252("5.9.3.5") GATEWAY_TIMEOUT = 5*04);
code!(rfc7252("5.9.3.6") PROXYING_NOT_SUPPORTED = 5*05);
12 changes: 6 additions & 6 deletions toad/src/resp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,13 @@ impl<P: PlatformTypes> Resp<P> {

/// Create a response ACKnowledging an incoming request.
///
/// An ack response must be used when you receive
/// a CON request.
/// Received CON requests will be continually retried until
/// ACKed, making it very important that we acknowledge them
/// quickly on receipt.
///
/// You may choose to include the response payload in an ACK,
/// but keep in mind that you might receive duplicate
/// If you do need to ensure they receive your response,
/// you
/// Servers may choose to include a response to the request
/// along with the ACK (entailing a response [`Code`] and [`Payload`]),
/// as long as care is taken to not delay between receipt and ACK.
pub fn ack(req: &Req<P>) -> Self {
let msg = Message { ty: Type::Ack,
id: req.msg().id,
Expand Down
4 changes: 2 additions & 2 deletions toad/src/step/ack.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use toad_array::Array;
use toad_array::{Array, Indexed};
use toad_msg::{CodeKind, Type};

use super::{exec_inner_step, Step, StepOutput};
Expand Down Expand Up @@ -50,7 +50,7 @@ impl<Inner: Step<P, PollReq = InnerPollReq<P>, PollResp = InnerPollResp<P>>, P:
if req.data().as_ref().ty == Type::Con
&& req.data().as_ref().code.kind() == CodeKind::Request =>
{
effects.push(Effect::Send(Addrd(Resp::ack(req.as_ref().data()).into(), req.addr())));
effects.append(Effect::Send(Addrd(Resp::ack(req.as_ref().data()).into(), req.addr())));
Some(Ok(req))
},
| Some(req) => Some(Ok(req)),
Expand Down
Loading