Skip to content

Commit

Permalink
current state of refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
LimpidCrypto committed Aug 18, 2024
1 parent 4ef657d commit 7769131
Show file tree
Hide file tree
Showing 25 changed files with 556 additions and 665 deletions.
31 changes: 31 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/rust
{
"name": "Rust",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",
// Use 'mounts' to make the cargo cache persistent in a Docker Volume.
// "mounts": [
// {
// "source": "devcontainer-cargo-cache-${devcontainerId}",
// "target": "/usr/local/cargo",
// "type": "volume"
// }
// ]
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "rustc --version",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"swellaby.rust-pack"
]
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot

version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: weekly
120 changes: 59 additions & 61 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,81 +10,79 @@ name = "em_as_net"
crate-type = ["lib"]

[dependencies]
anyhow = { version = "1.0.68", default-features = false }
heapless = { version = "0.7.16", default-features = false }
heapless = { version = "0.8.0", default-features = false }
libc = { version = "0.2.139", default-features = false }
rand = { version = "0.8.5", default-features = false, features = ["getrandom"] }
rand_core = { version = "0.6.4", default-features = false }
static_cell = { version = "1.0", default-features = false }
static_cell = { version = "2.1.0", default-features = false }
# Error handling
thiserror-no-std = { version = "2.0.2", default-features = false }
futures = { version = "0.3.25", default-features = false }
embedded-tls = { version = "0.14.1", default-features = false, features = ["async"], optional = true }
reqwless = "0.5.0"
tokio = { version = "1.27.0", default-features = false, optional = true }
async-std = { version = "1.12.0", features = ["attributes", "tokio1"], default-features = false, optional = true }
tokio-rustls = { version = "0.24.1", optional = true }
tokio-util = { version = "0.7.7", optional = true }
bytes = { version = "1.4.0", default-features = false }
embedded-io = { version = "0.4.0", features = ["async"] }
pin-project-lite = "0.2.9"
strum_macros = { version = "0.25.1", default-features = false }
anyhow = { version = "1.0.68", default-features = false }
# URL
url = { version = "2.3.1", default-features = false }
embedded-nal-async = "0.4.0"
tokio-tungstenite = { version = "0.20.0", optional = true }
# TCP
tokio = { version = "1.39.2", features = [
"macros",
"rt-multi-thread",
], optional = true }
embassy-net = { version = "0.4.0", features = [
"tcp",
"medium-ethernet",
"dhcpv4",
"proto-ipv6",
] }
embedded-io-async = "0.6.1"
embedded-io-adapters = "0.6.1"
# DNS
embedded-nal-async = "0.7.1"
# TLS
rustls = { version = "0.23.12", default-features = false, features = ["tls12"] }
tokio-rustls = { version = "0.26.0", optional = true }
# Web Socket
embedded-websocket = { git = "https://github.com/LimpidCrypto/embedded-websocket", branch = "update-dep-and-embedded-io-async", features = [
"embedded-io-async",
], optional = true }
# JSON-RPC
reqwless = "0.12.1"
webpki-roots = { version = "0.26.3", optional = true }
rand_core = "0.6.4"

[dependencies.embedded-websocket]
# git version needed to use `framer_async`
git = "https://github.com/ninjasource/embedded-websocket"
version = "0.9.2"
default-features = false

[dependencies.embassy-net]
git = "https://github.com/embassy-rs/embassy"
package = "embassy-net"
version = "0.1.0"
rev = "5d5cd2371504915a531e669dce3558485a51a2e1"
features = ["nightly", "tcp", "medium-ethernet", "dhcpv4", "proto-ipv6"]

[dependencies.embassy-net-driver]
git = "https://github.com/embassy-rs/embassy"
package = "embassy-net-driver"
version = "0.1.0"
rev = "83ff3cbc69875f93c5a9bb36825c12df39f04f71"

[dependencies.embassy-futures]
git = "https://github.com/embassy-rs/embassy"
package = "embassy-futures"
version = "0.1.0"
rev = "9e8de5f596ffa9036c2343ccc1e69f471a4770eb"

[dependencies.embassy-time]
git = "https://github.com/embassy-rs/embassy"
package = "embassy-time"
version = "0.1.0"
rev = "dff9bd9711205fd4cd5a91384072ab6aa2335d18"
# strum_macros = { version = "0.26.4", default-features = false }
# async-std = { version = "1.12.0", features = [
# "attributes",
# "tokio1",
# ], default-features = false, optional = true }
# tokio-util = { version = "0.7.7", optional = true }
# bytes = { version = "1.4.0", default-features = false }
# pin-project-lite = "0.2.9"
# embassy-net-driver = "0.2.0"
# embassy-futures = "0.1.1"
# embassy-time = "0.3.1"
# futures = { version = "0.3.25", default-features = false }
# rand = { version = "0.8.5", default-features = false, features = ["getrandom"] }
# rand_core = { version = "0.6.4", default-features = false }

[dev-dependencies]
tokio = { version = "1.27.0", features = ["full"] }

[features]
default = ["std", "dns", "websocket", "json-rpc"] # TODO: Add tls as soon as it's working
default = [
"std",
"tcp",
"dns",
"tls",
"websocket",
"json-rpc",
] # TODO: Add tls as soon as it's working
tcp = []
dns = ["embassy-net/dns"]
tls = ["embedded-tls"]
tls = []
websocket = []
json-rpc = []
std = [
"tokio/full",
"dep:tokio",
"embedded-io-adapters/tokio-1",
"embedded-websocket/std",
"embedded-tls/std",
"embedded-tls/tokio",
"async-std",
"tokio-rustls",
"tokio-util/codec",
"embassy-net/std",
"embassy-time/std",
"embassy-time/generic-queue",
"rand/std",
"rand/std_rng",
"futures/std",
"tokio-tungstenite/native-tls",
"webpki-roots",
]
webpki-roots = ["dep:webpki-roots"]
3 changes: 2 additions & 1 deletion src/client/websocket/async_websocket_client.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{client::websocket::errors::WebsocketError, Err};

use alloc::string::ToString;
use anyhow::Result;
use core::{
fmt::{Debug, Display},
Expand Down Expand Up @@ -141,7 +142,7 @@ impl
WebsocketOpen,
>,
> {
let (websocket_stream, _) = tungstenite_connect_async(uri).await.unwrap();
let (websocket_stream, _) = tungstenite_connect_async(uri.to_string()).await.unwrap();

Ok(AsyncWebsocketClient {
inner: websocket_stream,
Expand Down
44 changes: 0 additions & 44 deletions src/client/websocket/errors.rs

This file was deleted.

49 changes: 49 additions & 0 deletions src/client/websocket/exceptions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use anyhow::anyhow;
use core::fmt::Debug;
use core::str::Utf8Error;
use embedded_websocket::framer_async::FramerError;
use thiserror_no_std::Error;

#[derive(Debug, PartialEq, Eq, Error)]
pub enum WebsocketError<E: Debug> {
#[error("Stream is not connected.")]
NotConnected,
// FramerError
#[error("I/O error: {0:?}")]
Io(E),
#[error("Frame too large (size: {0:?})")]
FrameTooLarge(usize),
#[error("Failed to interpret u8 to string (error: {0:?})")]
Utf8(Utf8Error),
#[error("Invalid HTTP header")]
HttpHeader,
#[error("Websocket error: {0:?}")]
WebSocket(embedded_websocket::Error),
#[error("Disconnected")]
Disconnected,
#[error("Read buffer is too small (size: {0:?})")]
RxBufferTooSmall(usize),
}

impl<E: Debug> From<FramerError<E>> for WebsocketError<E> {
fn from(e: FramerError<E>) -> Self {
match e {
FramerError::Io(e) => WebsocketError::Io(e),
FramerError::FrameTooLarge(size) => WebsocketError::FrameTooLarge(size),
FramerError::Utf8(e) => WebsocketError::Utf8(e),
FramerError::HttpHeader(_) => WebsocketError::HttpHeader,
FramerError::WebSocket(e) => WebsocketError::WebSocket(e),
FramerError::Disconnected => WebsocketError::Disconnected,
FramerError::RxBufferTooSmall(size) => WebsocketError::RxBufferTooSmall(size),
}
}
}

impl<E: Debug> Into<anyhow::Error> for WebsocketError<E> {
fn into(self) -> anyhow::Error {
anyhow!(self)
}
}

#[cfg(feature = "std")]
impl<E: Debug> alloc::error::Error for WebsocketError<E> {}
78 changes: 75 additions & 3 deletions src/client/websocket/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,76 @@
mod async_websocket_client;
pub mod errors;
pub mod exceptions;

pub use async_websocket_client::*;
use core::marker::PhantomData;

use alloc::string::ToString;
use anyhow::Result;
use embedded_io_async::{Read, Write};
use embedded_websocket::{framer_async::Framer, Client, WebSocketClient, WebSocketOptions};
use exceptions::WebsocketError;
use rand_core::RngCore;
use url::Url;

use crate::Err;

pub struct WebsocketClosed;
pub struct WebsocketOpen;

pub struct AsyncWebsocketClient<T: RngCore, Status = WebsocketClosed> {
inner: Framer<T, Client>,
status: PhantomData<Status>,
}

impl<T: RngCore, Status> AsyncWebsocketClient<T, Status> {
pub fn is_open(&self) -> bool {
core::any::type_name::<Status>() == core::any::type_name::<WebsocketOpen>()
}
}

impl<T: RngCore> AsyncWebsocketClient<T, WebsocketClosed> {
pub async fn open<S>(
buf: &mut [u8],
stream: &mut S,
uri: Url,
rng: T,
) -> Result<AsyncWebsocketClient<T, WebsocketOpen>>
where
S: Read + Write + Unpin,
{
// replace the scheme with http or https
let scheme = match uri.scheme() {
"wss" => "https",
"ws" => "http",
_ => uri.scheme(),
};
let port = match uri.port() {
Some(port) => port,
None => match uri.scheme() {
"wss" => 443,
"ws" => 80,
_ => 80,
},
}
.to_string();
let path = uri.path();
let host = match uri.host_str() {
Some(host) => host,
None => return Err(WebsocketError::Disconnected.into()),
};
let origin = scheme.to_string() + "://" + host + ":" + &port + path;
let websocket_options = WebSocketOptions {
path,
host,
origin: &origin,
sub_protocols: None,
additional_headers: None,
};
let websocket = Framer::new(WebSocketClient::new_client(rng));
match websocket.connect(stream, buf, &websocket_options).await {
Ok(_) => Ok(AsyncWebsocketClient {
inner: websocket,
status: PhantomData::<WebsocketOpen>,
}),
Err(e) => Err!(e),
}
}
}
Loading

0 comments on commit 7769131

Please sign in to comment.