mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-20 13:26:34 +00:00
Test on wasm32-unknown-unknown (#806)
* Test on wasm32-unknown-unknown * Fix compilation
This commit is contained in:
@ -5,7 +5,6 @@ workflows:
|
||||
build:
|
||||
jobs:
|
||||
- test
|
||||
- test-emscripten
|
||||
- test-wasm
|
||||
- test-win32
|
||||
- integration-test
|
||||
@ -43,34 +42,18 @@ jobs:
|
||||
paths:
|
||||
- "/cache"
|
||||
|
||||
test-emscripten:
|
||||
docker:
|
||||
- image: tomaka/rustc-emscripten
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: test-emscripten-cache
|
||||
- run:
|
||||
name: Build for emscripten
|
||||
command: cargo build --target asmjs-unknown-emscripten --package libp2p
|
||||
- save_cache:
|
||||
key: test-emscripten-cache
|
||||
paths:
|
||||
- "~/.cargo"
|
||||
- "./target"
|
||||
|
||||
test-wasm:
|
||||
docker:
|
||||
- image: tomaka/rustc-emscripten
|
||||
- image: tomaka/rustc-emscripten:try-cargo-web
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: test-wasm-cache
|
||||
- run:
|
||||
name: Build for wasm32
|
||||
# TODO: we use --release because of https://github.com/rust-lang/rust/issues/49467
|
||||
# TODO: build libp2p instead of libp2p-core
|
||||
command: cargo build --target wasm32-unknown-unknown --package libp2p-core --release
|
||||
# TODO: also run tests but with --no-run; important to detect linking errors
|
||||
# TODO: secp doesn't compile for wasm yet
|
||||
command: cargo web build --no-default-features --features "libp2p-websocket"
|
||||
- save_cache:
|
||||
key: test-wasm-cache
|
||||
paths:
|
||||
|
@ -35,13 +35,13 @@ tokio-codec = "0.1"
|
||||
tokio-executor = "0.1"
|
||||
tokio-io = "0.1"
|
||||
|
||||
[target.'cfg(not(target_os = "emscripten"))'.dependencies]
|
||||
[target.'cfg(not(any(target_os = "emscripten", target_os = "unknown")))'.dependencies]
|
||||
libp2p-dns = { version = "0.1.0", path = "./transports/dns" }
|
||||
libp2p-mdns = { version = "0.1.0", path = "./misc/mdns" }
|
||||
libp2p-tcp = { version = "0.1.0", path = "./transports/tcp" }
|
||||
|
||||
[target.'cfg(target_os = "emscripten")'.dependencies]
|
||||
stdweb = { version = "0.1.3", default-features = false }
|
||||
[target.'cfg(any(target_os = "emscripten", target_os = "unknown"))'.dependencies]
|
||||
stdweb = { version = "0.4", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.6.0"
|
||||
|
@ -17,7 +17,7 @@ libp2p-core = { version = "0.1.0", path = "../../core" }
|
||||
log = "0.4.1"
|
||||
protobuf = "2.0.2"
|
||||
rand = "0.6"
|
||||
secp256k1 = {version = "0.11", optional = true }
|
||||
secp256k1 = { version = "0.12", features = ["rand"], optional = true }
|
||||
aes-ctr = "0.1.0"
|
||||
aesni = { version = "0.4.1", features = ["nocheck"], optional = true }
|
||||
twofish = "0.1.0"
|
||||
@ -29,12 +29,12 @@ sha2 = "0.7.1"
|
||||
ed25519-dalek = "0.8.0"
|
||||
hmac = "0.6.3"
|
||||
|
||||
[target.'cfg(not(target_os = "emscripten"))'.dependencies]
|
||||
[target.'cfg(not(any(target_os = "emscripten", target_os = "unknown")))'.dependencies]
|
||||
ring = { version = "0.12", default-features = false }
|
||||
untrusted = { version = "0.5" }
|
||||
|
||||
[target.'cfg(target_os = "emscripten")'.dependencies]
|
||||
stdweb = { version = "0.4.8", default-features = false }
|
||||
[target.'cfg(any(target_os = "emscripten", target_os = "unknown"))'.dependencies]
|
||||
stdweb = { version = "0.4", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["rsa", "secp256k1"]
|
||||
|
@ -24,7 +24,7 @@
|
||||
//! helps you with.
|
||||
|
||||
use crate::error::SecioError;
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
use ring::digest;
|
||||
use std::cmp::Ordering;
|
||||
use crate::stream_cipher::Cipher;
|
||||
@ -204,7 +204,7 @@ pub fn select_digest(r: Ordering, ours: &str, theirs: &str) -> Result<Digest, Se
|
||||
Err(SecioError::NoSupportIntersection)
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
impl Into<&'static digest::Algorithm> for Digest {
|
||||
#[inline]
|
||||
fn into(self) -> &'static digest::Algorithm {
|
||||
|
@ -24,10 +24,10 @@ use futures::prelude::*;
|
||||
use crate::SecioError;
|
||||
|
||||
#[path = "impl_ring.rs"]
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
mod platform;
|
||||
#[path = "impl_webcrypto.rs"]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
mod platform;
|
||||
|
||||
/// Possible key agreement algorithms.
|
||||
|
@ -34,9 +34,9 @@ use log::{debug, trace};
|
||||
use protobuf::parse_from_bytes as protobuf_parse_from_bytes;
|
||||
use protobuf::Message as ProtobufMessage;
|
||||
use rand::{self, RngCore};
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
use ring::signature::{RSASigningState, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_SHA256, verify as ring_verify};
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
use ring::rand::SystemRandom;
|
||||
#[cfg(feature = "secp256k1")]
|
||||
use secp256k1;
|
||||
@ -46,7 +46,7 @@ use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
||||
use crate::structs_proto::{Exchange, Propose};
|
||||
use tokio_io::codec::length_delimited;
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
use untrusted::Input as UntrustedInput;
|
||||
use crate::{KeyAgreement, SecioConfig, SecioKeyPairInner};
|
||||
|
||||
@ -368,7 +368,7 @@ where
|
||||
exchange.set_epubkey(tmp_pub_key);
|
||||
exchange.set_signature({
|
||||
match context.config.key.inner {
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
SecioKeyPairInner::Rsa { ref private, .. } => {
|
||||
let mut state = match RSASigningState::new(private.clone()) {
|
||||
Ok(s) => s,
|
||||
@ -401,7 +401,7 @@ where
|
||||
let secp256k1 = secp256k1::Secp256k1::signing_only();
|
||||
secp256k1
|
||||
.sign(&message, private)
|
||||
.serialize_der(&secp256k1)
|
||||
.serialize_der()
|
||||
},
|
||||
}
|
||||
});
|
||||
@ -452,7 +452,7 @@ where
|
||||
data_to_verify.extend_from_slice(remote_exch.get_epubkey());
|
||||
|
||||
match context.state.remote.public_key {
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
PublicKey::Rsa(ref remote_public_key) => {
|
||||
// TODO: The ring library doesn't like some stuff in our DER public key,
|
||||
// therefore we scrap the first 24 bytes of the key. A proper fix would
|
||||
@ -492,8 +492,8 @@ where
|
||||
let message = secp256k1::Message::from_slice(data_to_verify.as_ref())
|
||||
.expect("digest output length doesn't match secp256k1 input length");
|
||||
let secp256k1 = secp256k1::Secp256k1::verification_only();
|
||||
let signature = secp256k1::Signature::from_der(&secp256k1, remote_exch.get_signature());
|
||||
let remote_public_key = secp256k1::key::PublicKey::from_slice(&secp256k1, remote_public_key);
|
||||
let signature = secp256k1::Signature::from_der(remote_exch.get_signature());
|
||||
let remote_public_key = secp256k1::key::PublicKey::from_slice(remote_public_key);
|
||||
if let (Ok(signature), Ok(remote_public_key)) = (signature, remote_public_key) {
|
||||
match secp256k1.verify(&message, &signature, &remote_public_key) {
|
||||
Ok(()) => (),
|
||||
@ -507,7 +507,7 @@ where
|
||||
return Err(SecioError::SignatureVerificationFailed)
|
||||
}
|
||||
},
|
||||
#[cfg(not(all(feature = "ring", not(target_os = "emscripten"))))]
|
||||
#[cfg(not(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown")))))]
|
||||
PublicKey::Rsa(_) => {
|
||||
debug!("support for RSA was disabled at compile-time");
|
||||
return Err(SecioError::SignatureVerificationFailed);
|
||||
@ -640,7 +640,7 @@ mod tests {
|
||||
use crate::{SecioConfig, SecioKeyPair};
|
||||
|
||||
#[test]
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
fn handshake_with_self_succeeds_rsa() {
|
||||
let key1 = {
|
||||
let private = include_bytes!("../tests/test-rsa-private-key.pk8");
|
||||
|
@ -77,7 +77,7 @@
|
||||
|
||||
// TODO: unfortunately the `js!` macro of stdweb depends on tons of "private" macros, which we
|
||||
// don't want to import manually
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
#[macro_use]
|
||||
extern crate stdweb;
|
||||
|
||||
@ -91,7 +91,7 @@ use futures::stream::MapErr as StreamMapErr;
|
||||
use futures::{Future, Poll, Sink, StartSend, Stream};
|
||||
use libp2p_core::{PeerId, PublicKey, upgrade::{UpgradeInfo, InboundUpgrade, OutboundUpgrade}};
|
||||
use log::debug;
|
||||
#[cfg(all(feature = "rsa", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "rsa", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
use ring::signature::RSAKeyPair;
|
||||
use rw_stream_sink::RwStreamSink;
|
||||
use std::error::Error;
|
||||
@ -99,7 +99,7 @@ use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
||||
use std::iter;
|
||||
use std::sync::Arc;
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
#[cfg(all(feature = "rsa", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "rsa", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
use untrusted::Input;
|
||||
|
||||
mod algo_support;
|
||||
@ -209,7 +209,7 @@ pub struct SecioKeyPair {
|
||||
|
||||
impl SecioKeyPair {
|
||||
/// Builds a `SecioKeyPair` from a PKCS8 private key and public key.
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
pub fn rsa_from_pkcs8<P>(
|
||||
private: &[u8],
|
||||
public: P,
|
||||
@ -229,7 +229,7 @@ impl SecioKeyPair {
|
||||
|
||||
/// Generates a new Ed25519 key pair and uses it.
|
||||
pub fn ed25519_generated() -> Result<SecioKeyPair, Box<Error + Send + Sync>> {
|
||||
let mut csprng = rand::rngs::OsRng::new()?;
|
||||
let mut csprng = rand::thread_rng();
|
||||
let keypair: Ed25519KeyPair = Ed25519KeyPair::generate::<sha2::Sha512, _>(&mut csprng);
|
||||
Ok(SecioKeyPair {
|
||||
inner: SecioKeyPairInner::Ed25519 {
|
||||
@ -241,13 +241,7 @@ impl SecioKeyPair {
|
||||
/// Generates a new random sec256k1 key pair.
|
||||
#[cfg(feature = "secp256k1")]
|
||||
pub fn secp256k1_generated() -> Result<SecioKeyPair, Box<Error + Send + Sync>> {
|
||||
let secp = secp256k1::Secp256k1::new();
|
||||
// TODO: This will work once 0.11.5 is released. See https://github.com/rust-bitcoin/rust-secp256k1/pull/80#pullrequestreview-172681778
|
||||
// let private = secp256k1::key::SecretKey::new(&secp, &mut secp256k1::rand::thread_rng());
|
||||
use rand::Rng;
|
||||
let mut random_slice= [0u8; secp256k1::constants::SECRET_KEY_SIZE];
|
||||
rand::thread_rng().fill(&mut random_slice[..]);
|
||||
let private = secp256k1::key::SecretKey::from_slice(&secp, &random_slice).expect("slice has the right size");
|
||||
let private = secp256k1::key::SecretKey::new(&mut secp256k1::rand::thread_rng());
|
||||
Ok(SecioKeyPair {
|
||||
inner: SecioKeyPairInner::Secp256k1 { private },
|
||||
})
|
||||
@ -259,8 +253,7 @@ impl SecioKeyPair {
|
||||
where
|
||||
K: AsRef<[u8]>,
|
||||
{
|
||||
let secp = secp256k1::Secp256k1::without_caps();
|
||||
let private = secp256k1::key::SecretKey::from_slice(&secp, key.as_ref())?;
|
||||
let private = secp256k1::key::SecretKey::from_slice(key.as_ref())?;
|
||||
|
||||
Ok(SecioKeyPair {
|
||||
inner: SecioKeyPairInner::Secp256k1 { private },
|
||||
@ -287,7 +280,7 @@ impl SecioKeyPair {
|
||||
/// Returns the public key corresponding to this key pair.
|
||||
pub fn to_public_key(&self) -> PublicKey {
|
||||
match self.inner {
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
SecioKeyPairInner::Rsa { ref public, .. } => PublicKey::Rsa(public.clone()),
|
||||
SecioKeyPairInner::Ed25519 { ref key_pair } => {
|
||||
PublicKey::Ed25519(key_pair.public.as_bytes().to_vec())
|
||||
@ -313,7 +306,7 @@ impl SecioKeyPair {
|
||||
// Inner content of `SecioKeyPair`.
|
||||
#[derive(Clone)]
|
||||
enum SecioKeyPairInner {
|
||||
#[cfg(all(feature = "ring", not(target_os = "emscripten")))]
|
||||
#[cfg(all(feature = "ring", not(any(target_os = "emscripten", target_os = "unknown"))))]
|
||||
Rsa {
|
||||
public: Vec<u8>,
|
||||
// We use an `Arc` so that we can clone the enum.
|
||||
|
18
src/lib.rs
18
src/lib.rs
@ -75,7 +75,7 @@
|
||||
//! Example:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #[cfg(all(not(target_os = "emscripten"), feature = "libp2p-secio"))] {
|
||||
//! # #[cfg(all(any(target_os = "emscripten", target_os = "unknown"), feature = "libp2p-secio"))] {
|
||||
//! use libp2p::{Transport, tcp::TcpConfig, secio::{SecioConfig, SecioKeyPair}};
|
||||
//! let tcp = TcpConfig::new();
|
||||
//! let secio_upgrade = SecioConfig::new(SecioKeyPair::ed25519_generated().unwrap());
|
||||
@ -140,19 +140,19 @@ extern crate libp2p_core_derive;
|
||||
extern crate tokio_executor;
|
||||
|
||||
pub extern crate libp2p_core as core;
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
pub extern crate libp2p_dns as dns;
|
||||
pub extern crate libp2p_identify as identify;
|
||||
pub extern crate libp2p_kad as kad;
|
||||
pub extern crate libp2p_floodsub as floodsub;
|
||||
pub extern crate libp2p_mplex as mplex;
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
pub extern crate libp2p_mdns as mdns;
|
||||
pub extern crate libp2p_ping as ping;
|
||||
pub extern crate libp2p_plaintext as plaintext;
|
||||
pub extern crate libp2p_ratelimit as ratelimit;
|
||||
pub extern crate libp2p_secio as secio;
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
pub extern crate libp2p_tcp as tcp;
|
||||
pub extern crate libp2p_uds as uds;
|
||||
#[cfg(feature = "libp2p-websocket")]
|
||||
@ -222,11 +222,11 @@ struct CommonTransport {
|
||||
inner: CommonTransportInner
|
||||
}
|
||||
|
||||
#[cfg(all(not(target_os = "emscripten"), feature = "libp2p-websocket"))]
|
||||
#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "libp2p-websocket"))]
|
||||
type InnerImplementation = core::transport::OrTransport<dns::DnsConfig<tcp::TcpConfig>, websocket::WsConfig<dns::DnsConfig<tcp::TcpConfig>>>;
|
||||
#[cfg(all(not(target_os = "emscripten"), not(feature = "libp2p-websocket")))]
|
||||
#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), not(feature = "libp2p-websocket")))]
|
||||
type InnerImplementation = dns::DnsConfig<tcp::TcpConfig>;
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
type InnerImplementation = websocket::BrowserWsConfig;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -237,7 +237,7 @@ struct CommonTransportInner {
|
||||
impl CommonTransport {
|
||||
/// Initializes the `CommonTransport`.
|
||||
#[inline]
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
pub fn new() -> CommonTransport {
|
||||
let transport = tcp::TcpConfig::new();
|
||||
let transport = dns::DnsConfig::new(transport);
|
||||
@ -254,7 +254,7 @@ impl CommonTransport {
|
||||
|
||||
/// Initializes the `CommonTransport`.
|
||||
#[inline]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
pub fn new() -> CommonTransport {
|
||||
let inner = websocket::BrowserWsConfig::new();
|
||||
CommonTransport {
|
||||
|
@ -8,14 +8,14 @@ repository = "https://github.com/libp2p/rust-libp2p"
|
||||
keywords = ["peer-to-peer", "libp2p", "networking"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "emscripten")))'.dependencies]
|
||||
[target.'cfg(all(unix, any(target_os = "emscripten", target_os = "unknown")))'.dependencies]
|
||||
libp2p-core = { version = "0.1.0", path = "../../core" }
|
||||
log = "0.4.1"
|
||||
futures = "0.1"
|
||||
multiaddr = { package = "parity-multiaddr", version = "0.1.0", path = "../../misc/multiaddr" }
|
||||
tokio-uds = "0.2"
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "emscripten")))'.dev-dependencies]
|
||||
[target.'cfg(all(unix, any(target_os = "emscripten", target_os = "unknown")))'.dev-dependencies]
|
||||
tempfile = "3.0"
|
||||
tokio = "0.1"
|
||||
tokio-io = "0.1"
|
||||
|
@ -44,7 +44,7 @@
|
||||
//! The `UdsConfig` structs implements the `Transport` trait of the `core` library. See the
|
||||
//! documentation of `core` and of libp2p in general to learn how to use the `Transport` trait.
|
||||
|
||||
#![cfg(all(unix, not(target_os = "emscripten")))]
|
||||
#![cfg(all(unix, any(target_os = "emscripten", target_os = "unknown")))]
|
||||
|
||||
extern crate futures;
|
||||
extern crate libp2p_core;
|
||||
|
@ -16,12 +16,12 @@ log = "0.4.1"
|
||||
rw-stream-sink = { version = "0.1.0", path = "../../misc/rw-stream-sink" }
|
||||
tokio-io = "0.1"
|
||||
|
||||
[target.'cfg(not(target_os = "emscripten"))'.dependencies]
|
||||
[target.'cfg(not(any(target_os = "emscripten", target_os = "unknown")))'.dependencies]
|
||||
websocket = { version = "0.21.0", default-features = false, features = ["async", "async-ssl"] }
|
||||
|
||||
[target.'cfg(target_os = "emscripten")'.dependencies]
|
||||
stdweb = { version = "0.1.3", default-features = false }
|
||||
[target.'cfg(any(target_os = "emscripten", target_os = "unknown"))'.dependencies]
|
||||
stdweb = { version = "0.4", default-features = false }
|
||||
|
||||
[target.'cfg(not(target_os = "emscripten"))'.dev-dependencies]
|
||||
[target.'cfg(not(any(target_os = "emscripten", target_os = "unknown")))'.dev-dependencies]
|
||||
libp2p-tcp = { version = "0.1.0", path = "../tcp" }
|
||||
tokio = "0.1"
|
||||
|
@ -76,18 +76,18 @@ extern crate multiaddr;
|
||||
extern crate rw_stream_sink;
|
||||
extern crate tokio_io;
|
||||
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
#[macro_use]
|
||||
extern crate stdweb;
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
extern crate websocket;
|
||||
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
mod browser;
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
mod desktop;
|
||||
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
|
||||
pub use self::browser::{BrowserWsConfig, BrowserWsConn};
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
|
||||
pub use self::desktop::WsConfig;
|
||||
|
Reference in New Issue
Block a user