Skip to content

Commit

Permalink
Introduce rune::runtime::Formatter and more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Aug 23, 2023
1 parent f6a12fd commit d90b411
Show file tree
Hide file tree
Showing 21 changed files with 448 additions and 284 deletions.
16 changes: 9 additions & 7 deletions crates/rune-modules/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
//! ```
use rune::{Any, Module, Value, ContextError};
use rune::runtime::{Bytes, Protocol, Ref};
use rune::runtime::{Bytes, Ref, Formatter};
use std::fmt;
use std::fmt::Write;

Expand Down Expand Up @@ -77,8 +77,8 @@ pub fn module(_stdio: bool) -> Result<Module, ContextError> {
module.function_meta(RequestBuilder::header)?;
module.function_meta(RequestBuilder::body_bytes)?;

module.associated_function(Protocol::STRING_DISPLAY, Error::display)?;
module.associated_function(Protocol::STRING_DISPLAY, StatusCode::display)?;
module.function_meta(Error::string_display)?;
module.function_meta(StatusCode::string_display)?;
Ok(module)
}

Expand All @@ -95,8 +95,9 @@ impl From<reqwest::Error> for Error {
}

impl Error {
fn display(&self, buf: &mut String) -> fmt::Result {
write!(buf, "{}", self.inner)
#[rune::function(instance, protocol = STRING_DISPLAY)]
fn string_display(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.inner)
}
}

Expand Down Expand Up @@ -144,8 +145,9 @@ pub struct StatusCode {
}

impl StatusCode {
fn display(&self, buf: &mut String) -> fmt::Result {
write!(buf, "{}", self.inner)
#[rune::function(instance, protocol = STRING_DISPLAY)]
fn string_display(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.inner)
}
}

Expand Down
27 changes: 17 additions & 10 deletions crates/rune-modules/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//! ```
use rune::{Any, Module, ContextError};
use rune::runtime::{Bytes, Shared, Value, Protocol, VmResult};
use rune::runtime::{Bytes, Shared, Value, VmResult, Formatter};
use std::fmt;
use std::io;
use tokio::process;
Expand All @@ -43,13 +43,13 @@ pub fn module(_stdio: bool) -> Result<Module, ContextError> {
module.ty::<ExitStatus>()?;
module.ty::<Output>()?;

module.function(["Command", "new"], Command::new)?;
module.associated_function("spawn", Command::spawn)?;
module.associated_function("arg", Command::arg)?;
module.associated_function("args", Command::args)?;
module.associated_function("wait_with_output", Child::wait_with_output)?;
module.associated_function(Protocol::STRING_DISPLAY, ExitStatus::display)?;
module.associated_function("code", ExitStatus::code)?;
module.function_meta(Command::new)?;
module.function_meta(Command::spawn)?;
module.function_meta(Command::arg)?;
module.function_meta(Command::args)?;
module.function_meta(Child::wait_with_output)?;
module.function_meta(ExitStatus::string_display)?;
module.function_meta(ExitStatus::code)?;
Ok(module)
}

Expand All @@ -61,13 +61,15 @@ struct Command {

impl Command {
/// Construct a new command.
#[rune::function(path = Self::new)]
fn new(command: &str) -> Self {
Self {
inner: process::Command::new(command),
}
}

/// Add arguments.
#[rune::function(instance)]
fn args(&mut self, args: &[Value]) -> VmResult<()> {
for arg in args {
match arg {
Expand All @@ -84,11 +86,13 @@ impl Command {
}

/// Add an argument.
#[rune::function(instance)]
fn arg(&mut self, arg: &str) {
self.inner.arg(arg);
}

/// Spawn the command.
#[rune::function(instance)]
fn spawn(mut self) -> io::Result<Child> {
Ok(Child {
inner: Some(self.inner.spawn()?),
Expand All @@ -109,6 +113,7 @@ struct Child {
impl Child {
// Returns a future that will resolve to an Output, containing the exit
// status, stdout, and stderr of the child process.
#[rune::function(instance)]
async fn wait_with_output(self) -> VmResult<io::Result<Output>> {
let inner = match self.inner {
Some(inner) => inner,
Expand Down Expand Up @@ -148,11 +153,13 @@ struct ExitStatus {
}

impl ExitStatus {
fn display(&self, buf: &mut String) -> fmt::Result {
#[rune::function(protocol = STRING_DISPLAY)]
fn string_display(&self, f: &mut Formatter) -> fmt::Result {
use std::fmt::Write as _;
write!(buf, "{}", self.status)
write!(f, "{}", self.status)
}

#[rune::function]
fn code(&self) -> Option<i32> {
self.status.code()
}
Expand Down
5 changes: 3 additions & 2 deletions crates/rune/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ pub(crate) use rune_macros::__internal_impl_any;
///
/// ```
/// use rune::{Any, Module, ContextError};
/// use rune::runtime::Formatter;
/// use std::fmt::{self, Write};
///
/// #[derive(Any)]
Expand Down Expand Up @@ -471,8 +472,8 @@ pub(crate) use rune_macros::__internal_impl_any;
/// /// assert_eq!(format!("{}", string), "hello");
/// /// ```
/// #[rune::function(protocol = STRING_DISPLAY)]
/// fn display(&self, buffer: &mut std::string::String) -> fmt::Result {
/// write!(buffer, "{}", self.inner)
/// fn display(&self, f: &mut Formatter) -> fmt::Result {
/// write!(f, "{}", self.inner)
/// }
/// }
///
Expand Down
6 changes: 3 additions & 3 deletions crates/rune/src/modules/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::fmt::{self, Write};
use crate::no_std::prelude::*;

use crate as rune;
use crate::runtime::{Type, Value, VmResult};
use crate::runtime::{Formatter, Type, Value, VmResult};
use crate::{ContextError, Module};

/// Utilities for dynamic typing or type reflection.
Expand Down Expand Up @@ -53,8 +53,8 @@ fn type_of_val(value: Value) -> VmResult<Type> {
/// assert_eq!(format!("{}", any::Type::of_val(42)), "Type(0x1cad9186c9641c4f)");
/// ```
#[rune::function(instance, protocol = STRING_DISPLAY)]
fn format_type(ty: Type, buf: &mut String) -> fmt::Result {
write!(buf, "{:?}", ty)
fn format_type(ty: Type, f: &mut Formatter) -> fmt::Result {
write!(f, "{:?}", ty)
}

/// Get the type name of a value.
Expand Down
5 changes: 2 additions & 3 deletions crates/rune/src/modules/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use core::cmp::Ordering;
use core::fmt::{self, Write};

use crate as rune;
use crate::no_std::prelude::*;
use crate::runtime::{Protocol, Value, VmResult};
use crate::runtime::{Formatter, Protocol, Value, VmResult};
use crate::{ContextError, Module};

/// Construct the `std::cmp` module.
Expand Down Expand Up @@ -115,6 +114,6 @@ fn min(v1: Value, v2: Value) -> VmResult<Value> {
/// assert_eq!(format!("{:?}", Ordering::Less), "Less");
/// ```
#[rune::function(instance, protocol = STRING_DEBUG)]
fn ordering_string_debug(this: Ordering, s: &mut String) -> fmt::Result {
fn ordering_string_debug(this: Ordering, s: &mut Formatter) -> fmt::Result {
write!(s, "{:?}", this)
}
19 changes: 10 additions & 9 deletions crates/rune/src/modules/collections/hash_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::no_std::prelude::*;

use crate as rune;
use crate::runtime::{
EnvProtocolCaller, FromValue, Iterator, Key, ProtocolCaller, Value, VmErrorKind, VmResult,
EnvProtocolCaller, Formatter, FromValue, Iterator, Key, ProtocolCaller, Value, VmErrorKind,
VmResult,
};
use crate::{Any, ContextError, Module};

Expand Down Expand Up @@ -455,32 +456,32 @@ impl HashMap {
/// assert_eq!(format!("{:?}", map), "{1: \"a\"}");
/// ```
#[rune::function(protocol = STRING_DEBUG)]
fn string_debug(&self, s: &mut String) -> VmResult<fmt::Result> {
self.string_debug_with(s, &mut EnvProtocolCaller)
fn string_debug(&self, f: &mut Formatter) -> VmResult<fmt::Result> {
self.string_debug_with(f, &mut EnvProtocolCaller)
}

pub(crate) fn string_debug_with(
&self,
s: &mut String,
f: &mut Formatter,
caller: &mut impl ProtocolCaller,
) -> VmResult<fmt::Result> {
vm_write!(s, "{{");
vm_write!(f, "{{");

let mut it = self.map.iter().peekable();

while let Some((key, value)) = it.next() {
vm_write!(s, "{:?}: ", key);
vm_write!(f, "{:?}: ", key);

if let Err(fmt::Error) = vm_try!(value.string_debug_with(s, caller)) {
if let Err(fmt::Error) = vm_try!(value.string_debug_with(f, caller)) {
return VmResult::Ok(Err(fmt::Error));
}

if it.peek().is_some() {
vm_write!(s, ", ");
vm_write!(f, ", ");
}
}

vm_write!(s, "}}");
vm_write!(f, "}}");
VmResult::Ok(Ok(()))
}

Expand Down
85 changes: 73 additions & 12 deletions crates/rune/src/modules/collections/hash_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use core::iter;

use crate as rune;
use crate::no_std::collections;
use crate::no_std::prelude::*;

use crate::runtime::{
EnvProtocolCaller, Iterator, IteratorTrait, Key, Protocol, ProtocolCaller, Ref, Value, VmResult,
EnvProtocolCaller, Formatter, Iterator, IteratorTrait, Key, ProtocolCaller, Ref, Value,
VmResult,
};
use crate::{Any, ContextError, Module};

Expand All @@ -28,10 +28,10 @@ pub(super) fn setup(module: &mut Module) -> Result<(), ContextError> {
module.function_meta(HashSet::iter)?;
module.function_meta(clone)?;
module.function_meta(from)?;
module.associated_function(Protocol::INTO_ITER, HashSet::__rune_fn__iter)?;
module.function_meta(HashSet::into_iter)?;
module.function_meta(HashSet::string_debug)?;
module.associated_function(Protocol::PARTIAL_EQ, HashSet::partial_eq)?;
module.associated_function(Protocol::EQ, HashSet::eq)?;
module.function_meta(HashSet::partial_eq)?;
module.function_meta(HashSet::eq)?;
Ok(())
}

Expand Down Expand Up @@ -301,6 +301,18 @@ impl HashSet {
VmResult::Ok(Iterator::from("std::collections::set::Union", iter))
}

/// Iterate over the hash set.
///
/// # Examples
///
/// ```rune
/// use std::collections::HashSet;
///
/// let set = HashSet::from([3, 2, 1]);
/// let vec = set.iter().collect::<Vec>();
/// vec.sort();
/// assert_eq!(vec, [1, 2, 3]);
/// ```
#[rune::function]
fn iter(&self) -> Iterator {
let iter = self.set.clone().into_iter();
Expand All @@ -320,6 +332,28 @@ impl HashSet {
VmResult::Ok(())
}

/// Convert the set into an iterator.
///
/// # Examples
///
/// ```rune
/// use std::collections::HashSet;
///
/// let set = HashSet::from([3, 2, 1]);
/// let vec = [];
///
/// for value in set {
/// vec.push(value);
/// }
///
/// vec.sort();
/// assert_eq!(vec, [1, 2, 3]);
/// ```
#[rune::function(protocol = INTO_ITER)]
fn into_iter(&self) -> Iterator {
self.__rune_fn__iter()
}

/// Write a debug representation to a string.
///
/// This calls the [`STRING_DEBUG`] protocol over all elements of the
Expand All @@ -334,28 +368,28 @@ impl HashSet {
/// println!("{:?}", set);
/// ```
#[rune::function(protocol = STRING_DEBUG)]
fn string_debug(&self, s: &mut String) -> VmResult<fmt::Result> {
self.string_debug_with(s, &mut EnvProtocolCaller)
fn string_debug(&self, f: &mut Formatter) -> VmResult<fmt::Result> {
self.string_debug_with(f, &mut EnvProtocolCaller)
}

fn string_debug_with(
&self,
s: &mut String,
f: &mut Formatter,
_: &mut impl ProtocolCaller,
) -> VmResult<fmt::Result> {
vm_write!(s, "{{");
vm_write!(f, "{{");

let mut it = self.set.iter().peekable();

while let Some(value) = it.next() {
vm_write!(s, "{:?}", value);
vm_write!(f, "{:?}", value);

if it.peek().is_some() {
vm_write!(s, ", ");
vm_write!(f, ", ");
}
}

vm_write!(s, "}}");
vm_write!(f, "}}");
VmResult::Ok(Ok(()))
}

Expand All @@ -369,10 +403,37 @@ impl HashSet {
VmResult::Ok(HashSet { set })
}

/// Perform a partial equality test between two sets.
///
/// # Examples
///
/// # Examples
///
/// ```rune
/// use std::collections::HashSet;
///
/// let set = HashSet::from([1, 2, 3]);
/// assert_eq!(set, HashSet::from([1, 2, 3]));
/// assert_ne!(set, HashSet::from([2, 3, 4]));
/// ```
#[rune::function(protocol = PARTIAL_EQ)]
fn partial_eq(&self, other: &Self) -> bool {
self.set == other.set
}

/// Perform a total equality test between two sets.
///
/// # Examples
///
/// ```rune
/// use std::ops::eq;
/// use std::collections::HashSet;
///
/// let set = HashSet::from([1, 2, 3]);
/// assert!(eq(set, HashSet::from([1, 2, 3])));
/// assert!(!eq(set, HashSet::from([2, 3, 4])));
/// ```
#[rune::function(protocol = EQ)]
fn eq(&self, other: &Self) -> bool {
self.set == other.set
}
Expand Down
Loading

0 comments on commit d90b411

Please sign in to comment.