From 1ca1061c4f614124c76d5d78df3674540aff2175 Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Mon, 2 Sep 2024 20:16:33 -0300 Subject: [PATCH 1/3] Create net module --- crates/rune/src/modules/mod.rs | 1 + crates/rune/src/modules/net.rs | 163 +++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 crates/rune/src/modules/net.rs diff --git a/crates/rune/src/modules/mod.rs b/crates/rune/src/modules/mod.rs index 4dc6d917c..5c6b56702 100644 --- a/crates/rune/src/modules/mod.rs +++ b/crates/rune/src/modules/mod.rs @@ -32,6 +32,7 @@ pub mod io; pub mod iter; pub mod macros; pub mod mem; +pub mod net; pub mod num; pub mod object; pub mod ops; diff --git a/crates/rune/src/modules/net.rs b/crates/rune/src/modules/net.rs new file mode 100644 index 000000000..ded0b7c5a --- /dev/null +++ b/crates/rune/src/modules/net.rs @@ -0,0 +1,163 @@ +//! The networking module. + +use std::net; + +use crate as rune; +use crate::{Any, ContextError, Module}; + +/// The networking module. +#[rune::module(::std::net)] +pub fn module() -> Result { + let mut module = Module::from_meta(self::module_meta)?; + + module.ty::()?; + module.ty::()?; + + module.function_meta(SocketAddr::new__meta)?; + module.function_meta(SocketAddr::ip__meta)?; + module.function_meta(SocketAddr::set_ip__meta)?; + module.function_meta(SocketAddr::port__meta)?; + module.function_meta(SocketAddr::set_port__meta)?; + module.function_meta(SocketAddr::is_ipv4__meta)?; + module.function_meta(SocketAddr::is_ipv6__meta)?; + + module.function_meta(IpAddr::is_unspecified__meta)?; + module.function_meta(IpAddr::is_loopback__meta)?; + module.function_meta(IpAddr::is_multicast__meta)?; + module.function_meta(IpAddr::is_ipv4__meta)?; + module.function_meta(IpAddr::is_ipv6__meta)?; + module.function_meta(IpAddr::to_canonical__meta)?; + + Ok(module) +} + +/// An internet socket address, either IPv4 or IPv6. +#[derive(Debug, Any)] +#[rune(item = ::std::net)] +pub struct SocketAddr { + inner: net::SocketAddr, +} + +impl SocketAddr { + /// Creates a new socket address from an IP address and a port number. + #[rune::function(keep, path = Self::new)] + pub fn new(ip: IpAddr, port: u16) -> Self { + Self { + inner: net::SocketAddr::new(ip.inner, port), + } + } + + /// Returns the IP address associated with this socket address. + #[rune::function(instance, keep)] + pub fn ip(&self) -> IpAddr { + IpAddr { + inner: self.inner.ip(), + } + } + + /// Changes the IP address associated with this socket address. + #[rune::function(instance, keep)] + pub fn set_ip(&mut self, new_ip: IpAddr) { + self.inner.set_ip(new_ip.inner); + } + + /// Returns the port number associated with this socket address. + #[rune::function(instance, keep)] + pub fn port(&self) -> u16 { + self.inner.port() + } + + /// Changes the port number associated with this socket address. + #[rune::function(instance, keep)] + pub fn set_port(&mut self, new_port: u16) { + self.inner.set_port(new_port); + } + + /// Returns [`true`] if the IP address in this `SocketAddr` is an + /// `IPv4` address, and [`false`] otherwise. + #[rune::function(instance, keep)] + pub fn is_ipv4(&self) -> bool { + self.inner.is_ipv4() + } + + /// Returns [`true`] if the IP address in this `SocketAddr` is an + /// `IPv6` address, and [`false`] otherwise. + #[rune::function(instance, keep)] + pub fn is_ipv6(&self) -> bool { + self.inner.is_ipv6() + } +} + +impl SocketAddr { + /// Converts [`SocketAddr`] into a [`std::net::SocketAddr`]. + pub fn into_std(self) -> net::SocketAddr { + self.inner + } + + /// Creates a [`SocketAddr`] from a [`std::net::SocketAddr`]. + pub fn from_std(addr: net::SocketAddr) -> Self { + Self { inner: addr } + } +} + +/// An IP address, either IPv4 or IPv6. +#[derive(Debug, Any)] +#[rune(item = ::std::net)] +pub struct IpAddr { + inner: net::IpAddr, +} + +impl IpAddr { + /// Returns [`true`] for the special 'unspecified' address. + #[rune::function(instance, keep)] + pub fn is_unspecified(&self) -> bool { + self.inner.is_unspecified() + } + + /// Returns [`true`] if this is a loopback address. + #[rune::function(instance, keep)] + pub fn is_loopback(&self) -> bool { + self.inner.is_loopback() + } + + /// Returns [`true`] if this is a multicast address. + #[rune::function(instance, keep)] + pub fn is_multicast(&self) -> bool { + self.inner.is_multicast() + } + + /// Returns [`true`] if this address is an `IPv4` address, and [`false`] + /// otherwise. + #[rune::function(instance, keep)] + pub fn is_ipv4(&self) -> bool { + self.inner.is_ipv4() + } + + /// Returns [`true`] if this address is an `IPv6` address, and [`false`] + /// otherwise. + #[rune::function(instance, keep)] + pub fn is_ipv6(&self) -> bool { + self.inner.is_ipv6() + } + + /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped IPv6 addresses, otherwise it + /// returns `self` as-is. + #[rune::function(instance, keep)] + pub fn to_canonical(&self) -> IpAddr { + Self { + inner: self.inner.to_canonical(), + } + } +} + +impl IpAddr { + /// Converts [`IpAddr`] into a [`std::net::IpAddr`]. + pub fn into_std(self) -> net::IpAddr { + self.inner + } + + /// Creates a [`IpAddr`] from a [`std::net::IpAddr`]. + pub fn from_std(addr: net::IpAddr) -> Self { + Self { inner: addr } + } +} From 754a5e3c51dea8a4ac309c5ec6c1e8a03b415495 Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Mon, 16 Sep 2024 19:40:41 -0300 Subject: [PATCH 2/3] Move net module to rune-modules instead rune "core" modules --- crates/rune-modules/Cargo.toml | 2 ++ crates/rune-modules/src/lib.rs | 4 +++ .../src/modules => rune-modules/src}/net.rs | 34 +++++++++++++++---- crates/rune/src/modules/mod.rs | 1 - 4 files changed, 34 insertions(+), 7 deletions(-) rename crates/{rune/src/modules => rune-modules/src}/net.rs (86%) diff --git a/crates/rune-modules/Cargo.toml b/crates/rune-modules/Cargo.toml index 997e0e88e..595b54a75 100644 --- a/crates/rune-modules/Cargo.toml +++ b/crates/rune-modules/Cargo.toml @@ -21,6 +21,7 @@ full = [ "json", "toml", "fs", + "net", "process", "signal", "rand", @@ -32,6 +33,7 @@ time = ["tokio", "tokio?/time"] fs = ["tokio", "tokio?/fs"] http = ["reqwest"] json = ["serde_json"] +net = [] process = ["tokio/process", "rune/std"] signal = ["tokio/signal"] rand = ["nanorand"] diff --git a/crates/rune-modules/src/lib.rs b/crates/rune-modules/src/lib.rs index 8b5245922..de6508e29 100644 --- a/crates/rune-modules/src/lib.rs +++ b/crates/rune-modules/src/lib.rs @@ -33,6 +33,7 @@ //! * [io] //! * [json] //! * [macros] +//! * [net] //! * [process] //! * [rand] //! * [signal] @@ -52,6 +53,7 @@ //! * `io` for the [io module][io] //! * `json` for the [json module][json] //! * `macros` for the [macros module][macros] +//! * `net` for the [net module][net] //! * `process` for the [process module][process] //! * `rand` for the [rand module][rand] //! * `signal` for the [signal module][signal] @@ -66,6 +68,7 @@ //! [io]: https://docs.rs/rune-modules/0/rune_modules/io/ //! [json]: https://docs.rs/rune-modules/0/rune_modules/json/ //! [macros]: https://docs.rs/rune-modules/0/rune_modules/macros/ +//! [net]: https://docs.rs/rune-modules/0/rune_modules/net/ //! [process]: https://docs.rs/rune-modules/0/rune_modules/process/ //! [rand]: https://docs.rs/rune-modules/0/rune_modules/rand/ //! [signal]: https://docs.rs/rune-modules/0/rune_modules/signal/ @@ -119,6 +122,7 @@ modules! { {io, "io"}, {json, "json"}, {macros, "macros"}, + {net, "net"}, {process, "process"}, {rand, "rand"}, {signal, "signal"}, diff --git a/crates/rune/src/modules/net.rs b/crates/rune-modules/src/net.rs similarity index 86% rename from crates/rune/src/modules/net.rs rename to crates/rune-modules/src/net.rs index ded0b7c5a..ffed0a236 100644 --- a/crates/rune/src/modules/net.rs +++ b/crates/rune-modules/src/net.rs @@ -1,13 +1,35 @@ -//! The networking module. +//! The native `net` module for the [Rune Language]. +//! +//! [Rune Language]: https://rune-rs.github.io +//! +//! ## Usage +//! +//! Add the following to your `Cargo.toml`: +//! +//! ```toml +//! rune-modules = { version = "0.14.0", features = ["net"] } +//! ``` +//! +//! Install it into your context: +//! +//! ```rust +//! let mut context = rune::Context::with_default_modules()?; +//! context.install(rune_modules::net::module(true)?)?; +//! # Ok::<_, rune::support::Error>(()) +//! ``` +//! +//! Use it in Rune: +//! +//! ```rust,ignore +//! ``` use std::net; -use crate as rune; -use crate::{Any, ContextError, Module}; +use rune::{Any, ContextError, Module}; -/// The networking module. +/// Construct the `net` module. #[rune::module(::std::net)] -pub fn module() -> Result { +pub fn module(_stdio: bool) -> Result { let mut module = Module::from_meta(self::module_meta)?; module.ty::()?; @@ -33,7 +55,7 @@ pub fn module() -> Result { /// An internet socket address, either IPv4 or IPv6. #[derive(Debug, Any)] -#[rune(item = ::std::net)] +#[rune(item = ::net)] pub struct SocketAddr { inner: net::SocketAddr, } diff --git a/crates/rune/src/modules/mod.rs b/crates/rune/src/modules/mod.rs index 5c6b56702..4dc6d917c 100644 --- a/crates/rune/src/modules/mod.rs +++ b/crates/rune/src/modules/mod.rs @@ -32,7 +32,6 @@ pub mod io; pub mod iter; pub mod macros; pub mod mem; -pub mod net; pub mod num; pub mod object; pub mod ops; From a593fe88755e5e1f023f99e44213f5bbe72292c3 Mon Sep 17 00:00:00 2001 From: ramon-bernardo Date: Wed, 16 Oct 2024 21:12:25 -0300 Subject: [PATCH 3/3] Make const fn when possible --- crates/rune-modules/src/net.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/crates/rune-modules/src/net.rs b/crates/rune-modules/src/net.rs index ffed0a236..0022776ff 100644 --- a/crates/rune-modules/src/net.rs +++ b/crates/rune-modules/src/net.rs @@ -63,7 +63,7 @@ pub struct SocketAddr { impl SocketAddr { /// Creates a new socket address from an IP address and a port number. #[rune::function(keep, path = Self::new)] - pub fn new(ip: IpAddr, port: u16) -> Self { + pub const fn new(ip: IpAddr, port: u16) -> Self { Self { inner: net::SocketAddr::new(ip.inner, port), } @@ -71,7 +71,7 @@ impl SocketAddr { /// Returns the IP address associated with this socket address. #[rune::function(instance, keep)] - pub fn ip(&self) -> IpAddr { + pub const fn ip(&self) -> IpAddr { IpAddr { inner: self.inner.ip(), } @@ -85,7 +85,7 @@ impl SocketAddr { /// Returns the port number associated with this socket address. #[rune::function(instance, keep)] - pub fn port(&self) -> u16 { + pub const fn port(&self) -> u16 { self.inner.port() } @@ -98,26 +98,26 @@ impl SocketAddr { /// Returns [`true`] if the IP address in this `SocketAddr` is an /// `IPv4` address, and [`false`] otherwise. #[rune::function(instance, keep)] - pub fn is_ipv4(&self) -> bool { + pub const fn is_ipv4(&self) -> bool { self.inner.is_ipv4() } /// Returns [`true`] if the IP address in this `SocketAddr` is an /// `IPv6` address, and [`false`] otherwise. #[rune::function(instance, keep)] - pub fn is_ipv6(&self) -> bool { + pub const fn is_ipv6(&self) -> bool { self.inner.is_ipv6() } } impl SocketAddr { /// Converts [`SocketAddr`] into a [`std::net::SocketAddr`]. - pub fn into_std(self) -> net::SocketAddr { + pub const fn into_std(self) -> net::SocketAddr { self.inner } /// Creates a [`SocketAddr`] from a [`std::net::SocketAddr`]. - pub fn from_std(addr: net::SocketAddr) -> Self { + pub const fn from_std(addr: net::SocketAddr) -> Self { Self { inner: addr } } } @@ -132,40 +132,40 @@ pub struct IpAddr { impl IpAddr { /// Returns [`true`] for the special 'unspecified' address. #[rune::function(instance, keep)] - pub fn is_unspecified(&self) -> bool { + pub const fn is_unspecified(&self) -> bool { self.inner.is_unspecified() } /// Returns [`true`] if this is a loopback address. #[rune::function(instance, keep)] - pub fn is_loopback(&self) -> bool { + pub const fn is_loopback(&self) -> bool { self.inner.is_loopback() } /// Returns [`true`] if this is a multicast address. #[rune::function(instance, keep)] - pub fn is_multicast(&self) -> bool { + pub const fn is_multicast(&self) -> bool { self.inner.is_multicast() } /// Returns [`true`] if this address is an `IPv4` address, and [`false`] /// otherwise. #[rune::function(instance, keep)] - pub fn is_ipv4(&self) -> bool { + pub const fn is_ipv4(&self) -> bool { self.inner.is_ipv4() } /// Returns [`true`] if this address is an `IPv6` address, and [`false`] /// otherwise. #[rune::function(instance, keep)] - pub fn is_ipv6(&self) -> bool { + pub const fn is_ipv6(&self) -> bool { self.inner.is_ipv6() } /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped IPv6 addresses, otherwise it /// returns `self` as-is. #[rune::function(instance, keep)] - pub fn to_canonical(&self) -> IpAddr { + pub const fn to_canonical(&self) -> IpAddr { Self { inner: self.inner.to_canonical(), } @@ -174,12 +174,12 @@ impl IpAddr { impl IpAddr { /// Converts [`IpAddr`] into a [`std::net::IpAddr`]. - pub fn into_std(self) -> net::IpAddr { + pub const fn into_std(self) -> net::IpAddr { self.inner } /// Creates a [`IpAddr`] from a [`std::net::IpAddr`]. - pub fn from_std(addr: net::IpAddr) -> Self { + pub const fn from_std(addr: net::IpAddr) -> Self { Self { inner: addr } } }