-
Notifications
You must be signed in to change notification settings - Fork 88
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
modules: Create net module #820
Draft
ramon-bernardo
wants to merge
3
commits into
rune-rs:main
Choose a base branch
from
ramon-bernardo:net-module
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
//! 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 rune::{Any, ContextError, Module}; | ||
|
||
/// Construct the `net` module. | ||
#[rune::module(::std::net)] | ||
pub fn module(_stdio: bool) -> Result<Module, ContextError> { | ||
let mut module = Module::from_meta(self::module_meta)?; | ||
|
||
module.ty::<SocketAddr>()?; | ||
module.ty::<IpAddr>()?; | ||
|
||
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 = ::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 const 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 const 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 const 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 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 const fn is_ipv6(&self) -> bool { | ||
self.inner.is_ipv6() | ||
} | ||
} | ||
|
||
impl SocketAddr { | ||
/// Converts [`SocketAddr`] into a [`std::net::SocketAddr`]. | ||
pub const fn into_std(self) -> net::SocketAddr { | ||
self.inner | ||
} | ||
|
||
/// Creates a [`SocketAddr`] from a [`std::net::SocketAddr`]. | ||
pub const 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 const fn is_unspecified(&self) -> bool { | ||
self.inner.is_unspecified() | ||
} | ||
|
||
/// Returns [`true`] if this is a loopback address. | ||
#[rune::function(instance, keep)] | ||
pub const fn is_loopback(&self) -> bool { | ||
self.inner.is_loopback() | ||
} | ||
|
||
/// Returns [`true`] if this is a multicast address. | ||
#[rune::function(instance, keep)] | ||
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 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 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 const fn to_canonical(&self) -> IpAddr { | ||
Self { | ||
inner: self.inner.to_canonical(), | ||
} | ||
} | ||
} | ||
|
||
impl IpAddr { | ||
/// Converts [`IpAddr`] into a [`std::net::IpAddr`]. | ||
pub const fn into_std(self) -> net::IpAddr { | ||
self.inner | ||
} | ||
|
||
/// Creates a [`IpAddr`] from a [`std::net::IpAddr`]. | ||
pub const fn from_std(addr: net::IpAddr) -> Self { | ||
Self { inner: addr } | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a way to create an
IpAddr
. What is a preference: enum or constructors?The std is
IpAddr::V4(...)
orV6(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The target is "Whatever Rust does" unless there is a good reason to deviate. So an Enum seems like the answer right now.
Make sure to add doc tests which exercises the constructors and pattern matching over the various variants to make sure they are installed!