mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
update network dependencies
This commit is contained in:
parent
5ef75552d0
commit
a0a0e36246
@ -28,7 +28,7 @@ tokio = { version = "1.14", default-features = false, features = ["io-util", "ma
|
|||||||
tokio-stream = { version = "0.1.2", default-features = false }
|
tokio-stream = { version = "0.1.2", default-features = false }
|
||||||
#tracing and metrics
|
#tracing and metrics
|
||||||
tracing = { version = "0.1", default-features = false, features = ["attributes"]}
|
tracing = { version = "0.1", default-features = false, features = ["attributes"]}
|
||||||
prometheus = { version = "0.12", default-features = false, optional = true }
|
prometheus = { version = "0.13", default-features = false, optional = true }
|
||||||
#async
|
#async
|
||||||
futures-core = { version = "0.3", default-features = false }
|
futures-core = { version = "0.3", default-features = false }
|
||||||
futures-util = { version = "0.3.7", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3.7", default-features = false, features = ["std"] }
|
||||||
@ -46,19 +46,19 @@ lz-fear = { version = "0.1.1", optional = true }
|
|||||||
async-trait = "0.1.42"
|
async-trait = "0.1.42"
|
||||||
bytes = "^1"
|
bytes = "^1"
|
||||||
# faster HashMaps
|
# faster HashMaps
|
||||||
hashbrown = { version = ">=0.9, <0.12" }
|
hashbrown = { version = ">=0.9, <0.13" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tracing-subscriber = { version = "0.3.7", default-features = false, features = ["env-filter", "fmt", "time", "ansi", "smallvec"] }
|
tracing-subscriber = { version = "0.3.7", default-features = false, features = ["env-filter", "fmt", "time", "ansi", "smallvec"] }
|
||||||
tokio = { version = "1.14", default-features = false, features = ["io-std", "fs", "rt-multi-thread"] }
|
tokio = { version = "1.14", default-features = false, features = ["io-std", "fs", "rt-multi-thread"] }
|
||||||
futures-util = { version = "0.3.7", default-features = false, features = ["sink", "std"] }
|
futures-util = { version = "0.3.7", default-features = false, features = ["sink", "std"] }
|
||||||
clap = { version = "2.33", default-features = false }
|
clap = { version = "3.1.8", default-features = false, features = ["std", "color"] }
|
||||||
shellexpand = "2.0.0"
|
shellexpand = "2.0.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
prometheus-hyper = "0.1.2"
|
prometheus-hyper = "0.1.2"
|
||||||
criterion = { version = "0.3.4", features = ["default", "async_tokio"] }
|
criterion = { version = "0.3.4", features = ["default", "async_tokio"] }
|
||||||
#quic
|
#quic
|
||||||
rcgen = { version = "0.8.10"}
|
rcgen = { version = "0.9"}
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "speed"
|
name = "speed"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
//! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006
|
//! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006
|
||||||
//! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006 --mode=client
|
//! RUST_BACKTRACE=1 cargo run --example chat -- --trace=info --port 15006 --mode=client
|
||||||
//! ```
|
//! ```
|
||||||
use clap::{App, Arg};
|
use clap::{Command, Arg};
|
||||||
use std::{sync::Arc, thread, time::Duration};
|
use std::{sync::Arc, thread, time::Duration};
|
||||||
use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::RwLock};
|
use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::RwLock};
|
||||||
use tracing::*;
|
use tracing::*;
|
||||||
@ -14,13 +14,13 @@ use veloren_network::{ConnectAddr, ListenAddr, Network, Participant, Pid, Promis
|
|||||||
/// between participants, it's neither pretty nor perfect, but it should show
|
/// between participants, it's neither pretty nor perfect, but it should show
|
||||||
/// how to integrate network
|
/// how to integrate network
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("Chat example")
|
let matches = Command::new("Chat example")
|
||||||
.version("0.1.0")
|
.version("0.1.0")
|
||||||
.author("Marcel Märtens <marcel.cochem@googlemail.com>")
|
.author("Marcel Märtens <marcel.cochem@googlemail.com>")
|
||||||
.about("example chat implemented with veloren-network")
|
.about("example chat implemented with veloren-network")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("mode")
|
Arg::new("mode")
|
||||||
.short("m")
|
.short('m')
|
||||||
.long("mode")
|
.long("mode")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.possible_values(&["server", "client", "both"])
|
.possible_values(&["server", "client", "both"])
|
||||||
@ -31,22 +31,22 @@ fn main() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("port")
|
Arg::new("port")
|
||||||
.short("p")
|
.short('p')
|
||||||
.long("port")
|
.long("port")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("52000")
|
.default_value("52000")
|
||||||
.help("port to listen on"),
|
.help("port to listen on"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("ip")
|
Arg::new("ip")
|
||||||
.long("ip")
|
.long("ip")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("127.0.0.1")
|
.default_value("127.0.0.1")
|
||||||
.help("ip to listen and connect to"),
|
.help("ip to listen and connect to"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("protocol")
|
Arg::new("protocol")
|
||||||
.long("protocol")
|
.long("protocol")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("tcp")
|
.default_value("tcp")
|
||||||
@ -56,8 +56,8 @@ fn main() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("trace")
|
Arg::new("trace")
|
||||||
.short("t")
|
.short('t')
|
||||||
.long("trace")
|
.long("trace")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("warn")
|
.default_value("warn")
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
//! --profile=release -Z unstable-options -- --trace=info --port 15006)
|
//! --profile=release -Z unstable-options -- --trace=info --port 15006)
|
||||||
//! (cd network/examples/fileshare && RUST_BACKTRACE=1 cargo run
|
//! (cd network/examples/fileshare && RUST_BACKTRACE=1 cargo run
|
||||||
//! --profile=release -Z unstable-options -- --trace=info --port 15007) ```
|
//! --profile=release -Z unstable-options -- --trace=info --port 15007) ```
|
||||||
use clap::{App, Arg, SubCommand};
|
use clap::{Command, Arg};
|
||||||
use std::{path::PathBuf, sync::Arc, thread, time::Duration};
|
use std::{path::PathBuf, sync::Arc, thread, time::Duration};
|
||||||
use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::mpsc};
|
use tokio::{io, io::AsyncBufReadExt, runtime::Runtime, sync::mpsc};
|
||||||
use tracing::*;
|
use tracing::*;
|
||||||
@ -16,21 +16,21 @@ use commands::{FileInfo, LocalCommand};
|
|||||||
use server::Server;
|
use server::Server;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("File Server")
|
let matches = Command::new("File Server")
|
||||||
.version("0.1.0")
|
.version("0.1.0")
|
||||||
.author("Marcel Märtens <marcel.cochem@googlemail.com>")
|
.author("Marcel Märtens <marcel.cochem@googlemail.com>")
|
||||||
.about("example file server implemented with veloren-network")
|
.about("example file server implemented with veloren-network")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("port")
|
Arg::new("port")
|
||||||
.short("p")
|
.short('p')
|
||||||
.long("port")
|
.long("port")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("15006")
|
.default_value("15006")
|
||||||
.help("port to listen on"),
|
.help("port to listen on"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("trace")
|
Arg::new("trace")
|
||||||
.short("t")
|
.short('t')
|
||||||
.long("trace")
|
.long("trace")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("warn")
|
.default_value("warn")
|
||||||
@ -61,8 +61,8 @@ fn main() {
|
|||||||
runtime.block_on(client(cmd_sender));
|
runtime.block_on(client(cmd_sender));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_exists(file: String) -> Result<(), String> {
|
fn file_exists(file: &str) -> Result<(), String> {
|
||||||
let file: std::path::PathBuf = shellexpand::tilde(&file).parse().unwrap();
|
let file: std::path::PathBuf = shellexpand::tilde(file).parse().unwrap();
|
||||||
if file.exists() {
|
if file.exists() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -70,22 +70,21 @@ fn file_exists(file: String) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_options<'a, 'b>() -> App<'a, 'b> {
|
fn get_options<'a>() -> Command<'a> {
|
||||||
App::new("")
|
Command::new("")
|
||||||
.setting(clap::AppSettings::NoBinaryName)
|
.no_binary_name(true)
|
||||||
.setting(clap::AppSettings::SubcommandRequired)
|
.subcommand_required(true)
|
||||||
.setting(clap::AppSettings::VersionlessSubcommands)
|
.arg_required_else_help(true)
|
||||||
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
|
.color(clap::ColorChoice::Auto)
|
||||||
.setting(clap::AppSettings::ColorAuto)
|
.subcommand(Command::new("quit").about("closes program"))
|
||||||
.subcommand(SubCommand::with_name("quit").about("closes program"))
|
.subcommand(Command::new("disconnect").about("stop connections to all servers"))
|
||||||
.subcommand(SubCommand::with_name("disconnect").about("stop connections to all servers"))
|
.subcommand(Command::new("t").about("quick test by connecting to 127.0.0.1:1231"))
|
||||||
.subcommand(SubCommand::with_name("t").about("quick test by connecting to 127.0.0.1:1231"))
|
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("connect")
|
Command::new("connect")
|
||||||
.about("opens a connection to another instance of this fileserver network")
|
.about("opens a connection to another instance of this fileserver network")
|
||||||
.setting(clap::AppSettings::NoBinaryName)
|
.no_binary_name(true)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("ip:port")
|
Arg::new("ip:port")
|
||||||
.help("ip and port to connect to, example '127.0.0.1:1231'")
|
.help("ip and port to connect to, example '127.0.0.1:1231'")
|
||||||
.required(true)
|
.required(true)
|
||||||
.validator(|ipport| match ipport.parse::<std::net::SocketAddr>() {
|
.validator(|ipport| match ipport.parse::<std::net::SocketAddr>() {
|
||||||
@ -94,26 +93,26 @@ fn get_options<'a, 'b>() -> App<'a, 'b> {
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.subcommand(SubCommand::with_name("list").about("lists all available files on the network"))
|
.subcommand(Command::new("list").about("lists all available files on the network"))
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("serve")
|
Command::new("serve")
|
||||||
.about("make file available on the network")
|
.about("make file available on the network")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("file")
|
Arg::new("file")
|
||||||
.help("file to serve")
|
.help("file to serve")
|
||||||
.required(true)
|
.required(true)
|
||||||
.validator(file_exists),
|
.validator(file_exists),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("get")
|
Command::new("get")
|
||||||
.about(
|
.about(
|
||||||
"downloads file with the id from the `list` command. Optionally provide a \
|
"downloads file with the id from the `list` command. Optionally provide a \
|
||||||
storage path, if none is provided it will be saved in the current directory \
|
storage path, if none is provided it will be saved in the current directory \
|
||||||
with the remote filename",
|
with the remote filename",
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("id")
|
Arg::new("id")
|
||||||
.help("id to download. get the id from the `list` command")
|
.help("id to download. get the id from the `list` command")
|
||||||
.required(true)
|
.required(true)
|
||||||
.validator(|id| match id.parse::<u32>() {
|
.validator(|id| match id.parse::<u32>() {
|
||||||
@ -121,7 +120,7 @@ fn get_options<'a, 'b>() -> App<'a, 'b> {
|
|||||||
Err(e) => Err(format!("must be a number {:?}", e)),
|
Err(e) => Err(format!("must be a number {:?}", e)),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.arg(Arg::with_name("file").help("local path to store the file to")),
|
.arg(Arg::new("file").help("local path to store the file to")),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,24 +133,28 @@ async fn client(cmd_sender: mpsc::UnboundedSender<LocalCommand>) {
|
|||||||
print!("==> ");
|
print!("==> ");
|
||||||
std::io::stdout().flush().unwrap();
|
std::io::stdout().flush().unwrap();
|
||||||
input_lines.read_line(&mut line).await.unwrap();
|
input_lines.read_line(&mut line).await.unwrap();
|
||||||
let matches = match get_options().get_matches_from_safe(line.split_whitespace()) {
|
let matches = match get_options().try_get_matches_from(line.split_whitespace()) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("{}", e.message);
|
println!("{}", e);
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
Ok(matches) => matches,
|
Ok(matches) => matches,
|
||||||
};
|
};
|
||||||
|
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
("quit", _) => {
|
None => {
|
||||||
|
println!("unknown subcommand");
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
Some(("quit", _)) => {
|
||||||
cmd_sender.send(LocalCommand::Shutdown).unwrap();
|
cmd_sender.send(LocalCommand::Shutdown).unwrap();
|
||||||
println!("goodbye");
|
println!("goodbye");
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
("disconnect", _) => {
|
Some(("disconnect", _)) => {
|
||||||
cmd_sender.send(LocalCommand::Disconnect).unwrap();
|
cmd_sender.send(LocalCommand::Disconnect).unwrap();
|
||||||
},
|
},
|
||||||
("connect", Some(connect_matches)) => {
|
Some(("connect", connect_matches)) => {
|
||||||
let socketaddr = connect_matches
|
let socketaddr = connect_matches
|
||||||
.value_of("ip:port")
|
.value_of("ip:port")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -161,24 +164,24 @@ async fn client(cmd_sender: mpsc::UnboundedSender<LocalCommand>) {
|
|||||||
.send(LocalCommand::Connect(ConnectAddr::Tcp(socketaddr)))
|
.send(LocalCommand::Connect(ConnectAddr::Tcp(socketaddr)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
},
|
||||||
("t", _) => {
|
Some(("t", _)) => {
|
||||||
cmd_sender
|
cmd_sender
|
||||||
.send(LocalCommand::Connect(ConnectAddr::Tcp(
|
.send(LocalCommand::Connect(ConnectAddr::Tcp(
|
||||||
"127.0.0.1:1231".parse().unwrap(),
|
"127.0.0.1:1231".parse().unwrap(),
|
||||||
)))
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
},
|
||||||
("serve", Some(serve_matches)) => {
|
Some(("serve", serve_matches)) => {
|
||||||
let path = shellexpand::tilde(serve_matches.value_of("file").unwrap());
|
let path = shellexpand::tilde(serve_matches.value_of("file").unwrap());
|
||||||
let path: PathBuf = path.parse().unwrap();
|
let path: PathBuf = path.parse().unwrap();
|
||||||
if let Some(fileinfo) = FileInfo::new(&path).await {
|
if let Some(fileinfo) = FileInfo::new(&path).await {
|
||||||
cmd_sender.send(LocalCommand::Serve(fileinfo)).unwrap();
|
cmd_sender.send(LocalCommand::Serve(fileinfo)).unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
("list", _) => {
|
Some(("list", _)) => {
|
||||||
cmd_sender.send(LocalCommand::List).unwrap();
|
cmd_sender.send(LocalCommand::List).unwrap();
|
||||||
},
|
},
|
||||||
("get", Some(get_matches)) => {
|
Some(("get", get_matches)) => {
|
||||||
let id: u32 = get_matches.value_of("id").unwrap().parse().unwrap();
|
let id: u32 = get_matches.value_of("id").unwrap().parse().unwrap();
|
||||||
let file = get_matches.value_of("file");
|
let file = get_matches.value_of("file");
|
||||||
cmd_sender
|
cmd_sender
|
||||||
@ -186,7 +189,7 @@ async fn client(cmd_sender: mpsc::UnboundedSender<LocalCommand>) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
},
|
||||||
|
|
||||||
(_, _) => {
|
Some((_, _)) => {
|
||||||
unreachable!("this subcommand isn't yet handled");
|
unreachable!("this subcommand isn't yet handled");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=server)
|
/// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=server)
|
||||||
/// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=client)
|
/// (cd network/examples/network-speed && RUST_BACKTRACE=1 cargo run --profile=debuginfo -Z unstable-options -- --trace=error --protocol=tcp --mode=client)
|
||||||
/// ```
|
/// ```
|
||||||
use clap::{App, Arg};
|
use clap::{Command, Arg};
|
||||||
use prometheus::Registry;
|
use prometheus::Registry;
|
||||||
use prometheus_hyper::Server;
|
use prometheus_hyper::Server;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -27,13 +27,13 @@ enum Msg {
|
|||||||
/// This utility tests the speed of veloren network by creating a client that
|
/// This utility tests the speed of veloren network by creating a client that
|
||||||
/// opens a stream and pipes as many messages through it as possible.
|
/// opens a stream and pipes as many messages through it as possible.
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("Veloren Speed Test Utility")
|
let matches = Command::new("Veloren Speed Test Utility")
|
||||||
.version("0.1.0")
|
.version("0.1.0")
|
||||||
.author("Marcel Märtens <marcel.cochem@googlemail.com>")
|
.author("Marcel Märtens <marcel.cochem@googlemail.com>")
|
||||||
.about("Runs speedtests regarding different parameter to benchmark veloren-network")
|
.about("Runs speedtests regarding different parameter to benchmark veloren-network")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("mode")
|
Arg::new("mode")
|
||||||
.short("m")
|
.short('m')
|
||||||
.long("mode")
|
.long("mode")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.possible_values(&["server", "client", "both"])
|
.possible_values(&["server", "client", "both"])
|
||||||
@ -44,22 +44,22 @@ fn main() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("port")
|
Arg::new("port")
|
||||||
.short("p")
|
.short('p')
|
||||||
.long("port")
|
.long("port")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("52000")
|
.default_value("52000")
|
||||||
.help("port to listen on"),
|
.help("port to listen on"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("ip")
|
Arg::new("ip")
|
||||||
.long("ip")
|
.long("ip")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("127.0.0.1")
|
.default_value("127.0.0.1")
|
||||||
.help("ip to listen and connect to"),
|
.help("ip to listen and connect to"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("protocol")
|
Arg::new("protocol")
|
||||||
.long("protocol")
|
.long("protocol")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("tcp")
|
.default_value("tcp")
|
||||||
@ -69,8 +69,8 @@ fn main() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("trace")
|
Arg::new("trace")
|
||||||
.short("t")
|
.short('t')
|
||||||
.long("trace")
|
.long("trace")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value("warn")
|
.default_value("warn")
|
||||||
|
@ -17,14 +17,14 @@ default = ["metrics"]
|
|||||||
|
|
||||||
#tracing and metrics
|
#tracing and metrics
|
||||||
tracing = { version = "0.1", default-features = false }
|
tracing = { version = "0.1", default-features = false }
|
||||||
prometheus = { version = "0.12", default-features = false, optional = true }
|
prometheus = { version = "0.13", default-features = false, optional = true }
|
||||||
#stream flags
|
#stream flags
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
rand = { version = "0.8" }
|
rand = { version = "0.8" }
|
||||||
# async traits
|
# async traits
|
||||||
async-trait = "0.1.42"
|
async-trait = "0.1.42"
|
||||||
bytes = "^1"
|
bytes = "^1"
|
||||||
hashbrown = { version = ">=0.9, <0.12" }
|
hashbrown = { version = ">=0.9, <0.13" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-channel = "1.5.1"
|
async-channel = "1.5.1"
|
||||||
|
Loading…
Reference in New Issue
Block a user