rune/modules/
result.rs

1//! The [`Result`] type.
2
3use core::cmp::Ordering;
4use core::hash::Hasher as _;
5
6use crate as rune;
7use crate::alloc::fmt::TryWrite;
8use crate::alloc::prelude::*;
9use crate::runtime::{
10    ControlFlow, EnvProtocolCaller, Formatter, Function, Hasher, Panic, Protocol, Value, VmError,
11};
12use crate::{hash_in, ContextError, Hash, Module};
13
14/// The [`Result`] type.
15///
16/// This module deals with the fundamental [`Result`] type in Rune.
17#[rune::module(::std::result)]
18pub fn module() -> Result<Module, ContextError> {
19    let mut m = Module::from_meta(self::module__meta)?;
20
21    // Sorted for ease of finding
22    let mut result = m
23        .ty::<Result<Value, Value>>()?
24        .static_docs(&["Result is a type that represents either success (Ok) or failure (Err)."])?
25        .make_enum(&["Ok", "Err"])?;
26
27    result
28        .variant_mut(0)?
29        .make_unnamed(1)?
30        .constructor(Result::Ok)?
31        .static_docs(&["Contains the success value"])?;
32
33    result
34        .variant_mut(1)?
35        .make_unnamed(1)?
36        .constructor(Result::Err)?
37        .static_docs(&["Contains the error value"])?;
38
39    m.function_meta(is_variant__meta)?;
40
41    m.index_function(
42        &Protocol::GET,
43        0,
44        |this: &Result<Value, Value>| match this {
45            Result::Ok(value) => value.clone(),
46            Result::Err(value) => value.clone(),
47        },
48    )?;
49
50    m.function_meta(ok)?;
51    m.function_meta(is_ok)?;
52    m.function_meta(is_err)?;
53    m.function_meta(unwrap)?;
54    m.function_meta(unwrap_or)?;
55    m.function_meta(unwrap_or_else)?;
56    m.function_meta(expect)?;
57    m.function_meta(and_then)?;
58    m.function_meta(map)?;
59
60    m.function_meta(clone__meta)?;
61    m.implement_trait::<Result<Value, Value>>(rune::item!(::std::clone::Clone))?;
62
63    m.function_meta(partial_eq__meta)?;
64    m.implement_trait::<Result<Value, Value>>(rune::item!(::std::cmp::PartialEq))?;
65
66    m.function_meta(eq__meta)?;
67    m.implement_trait::<Result<Value, Value>>(rune::item!(::std::cmp::Eq))?;
68
69    m.function_meta(partial_cmp__meta)?;
70    m.implement_trait::<Result<Value, Value>>(rune::item!(::std::cmp::PartialOrd))?;
71
72    m.function_meta(cmp__meta)?;
73    m.implement_trait::<Result<Value, Value>>(rune::item!(::std::cmp::Ord))?;
74
75    m.function_meta(hash__meta)?;
76    m.function_meta(debug_fmt__meta)?;
77
78    m.function_meta(result_try__meta)?;
79    Ok(m)
80}
81
82#[rune::function(instance, keep, protocol = IS_VARIANT)]
83#[inline]
84pub(crate) fn is_variant(this: &Result<Value, Value>, variant_hash: Hash) -> bool {
85    match (this, variant_hash) {
86        (Ok(..), hash_in!(crate, ::std::result::Result::Ok)) => true,
87        (Err(..), hash_in!(crate, ::std::result::Result::Err)) => true,
88        _ => false,
89    }
90}
91
92/// Converts from `Result` to `Option`.
93///
94/// # Examples
95///
96/// ```rune
97/// let a = Ok(2);
98/// let b = Err(3);
99///
100/// assert_eq!(a.ok(), Some(2));
101/// assert_eq!(b.ok(), None);
102/// ```
103#[rune::function(instance)]
104fn ok(result: &Result<Value, Value>) -> Option<Value> {
105    result.as_ref().ok().cloned()
106}
107
108/// Returns `true` if the result is [`Ok`].
109///
110/// # Examples
111///
112/// ```rune
113/// let x = Ok(-3);
114/// assert_eq!(x.is_ok(), true);
115///
116/// let x = Err("Some error message");
117/// assert_eq!(x.is_ok(), false);
118/// ```
119#[rune::function(instance)]
120fn is_ok(result: &Result<Value, Value>) -> bool {
121    result.is_ok()
122}
123
124/// Returns `true` if the result is [`Err`].
125///
126/// # Examples
127///
128/// ```rune
129/// let x = Ok(-3);
130/// assert_eq!(x.is_err(), false);
131///
132/// let x = Err("Some error message");
133/// assert_eq!(x.is_err(), true);
134/// ```
135#[rune::function(instance)]
136fn is_err(result: &Result<Value, Value>) -> bool {
137    result.is_err()
138}
139
140/// Returns the contained [`Ok`] value, consuming the `self` value.
141///
142/// Because this function may panic, its use is generally discouraged. Instead,
143/// prefer to use pattern matching and handle the [`Err`] case explicitly, or
144/// call [`unwrap_or`], [`unwrap_or_else`], or [`unwrap_or_default`].
145///
146/// [`unwrap_or`]: Result::unwrap_or
147/// [`unwrap_or_else`]: Result::unwrap_or_else
148/// [`unwrap_or_default`]: Result::unwrap_or_default
149///
150/// # Panics
151///
152/// Panics if the value is an [`Err`], with a panic message provided by the
153/// [`Err`]'s value.
154///
155/// # Examples
156///
157/// Basic usage:
158///
159/// ```rune
160/// let x = Ok(2);
161/// assert_eq!(x.unwrap(), 2);
162/// ```
163///
164/// ```rune,should_panic
165/// let x = Err("emergency failure");
166/// x.unwrap(); // panics with `emergency failure`
167/// ```
168#[rune::function(instance)]
169fn unwrap(result: &Result<Value, Value>) -> Result<Value, VmError> {
170    match result {
171        Ok(value) => Ok(value.clone()),
172        Err(err) => {
173            let mut m = String::new();
174            write!(m, "Called `Result::unwrap()` on an `Err` value: ")?;
175            Formatter::format_with(&mut m, |f| err.debug_fmt(f))?;
176            Err(VmError::from(Panic::custom(m)))
177        }
178    }
179}
180
181/// Returns the contained [`Ok`] value or a provided default.
182///
183/// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing
184/// the result of a function call, it is recommended to use [`unwrap_or_else`],
185/// which is lazily evaluated.
186///
187/// [`unwrap_or_else`]: Result::unwrap_or_else
188///
189/// # Examples
190///
191/// ```rune
192/// let default_value = 2;
193/// let x = Ok(9);
194/// assert_eq!(x.unwrap_or(default_value), 9);
195///
196/// let x = Err("error");
197/// assert_eq!(x.unwrap_or(default_value), default_value);
198/// ```
199#[rune::function(instance)]
200fn unwrap_or(this: &Result<Value, Value>, default: Value) -> Value {
201    match this {
202        Ok(value) => value.clone(),
203        Err(_) => default.clone(),
204    }
205}
206
207/// Returns the contained [`Ok`] value or computes it from a closure.
208///
209///
210/// # Examples
211///
212/// ```rune
213/// fn count(x) {
214///     x.len()
215/// }
216///
217/// assert_eq!(Ok(2).unwrap_or_else(count), 2);
218/// assert_eq!(Err("foo").unwrap_or_else(count), 3);
219/// ```
220#[rune::function(instance)]
221fn unwrap_or_else(this: &Result<Value, Value>, default: Function) -> Result<Value, VmError> {
222    match this {
223        Ok(value) => Ok(value.clone()),
224        Err(error) => default.call((error,)),
225    }
226}
227
228/// Returns the contained [`Ok`] value, consuming the `self` value.
229///
230/// Because this function may panic, its use is generally discouraged. Instead,
231/// prefer to use pattern matching and handle the [`Err`] case explicitly, or
232/// call [`unwrap_or`], [`unwrap_or_else`], or [`unwrap_or_default`].
233///
234/// [`unwrap_or`]: Result::unwrap_or
235/// [`unwrap_or_else`]: Result::unwrap_or_else
236/// [`unwrap_or_default`]: Result::unwrap_or_default
237///
238/// # Panics
239///
240/// Panics if the value is an [`Err`], with a panic message including the passed
241/// message, and the content of the [`Err`].
242///
243/// # Examples
244///
245/// ```rune,should_panic
246/// let x = Err("emergency failure");
247/// x.expect("Testing expect"); // panics with `Testing expect: emergency failure`
248/// ```
249///
250/// # Recommended Message Style
251///
252/// We recommend that `expect` messages are used to describe the reason you
253/// _expect_ the `Result` should be `Ok`. If you're having trouble remembering
254/// how to phrase expect error messages remember to focus on the word "should"
255/// as in "env variable should be set by blah" or "the given binary should be
256/// available and executable by the current user".
257#[rune::function(instance)]
258fn expect(result: &Result<Value, Value>, message: Value) -> Result<Value, VmError> {
259    match result {
260        Ok(value) => Ok(value.clone()),
261        Err(err) => {
262            let mut s = String::new();
263            Formatter::format_with(&mut s, |f| {
264                message.display_fmt(f)?;
265                f.try_write_str(": ")?;
266                err.debug_fmt(f)?;
267                Ok::<_, VmError>(())
268            })?;
269            Err(VmError::from(Panic::custom(s)))
270        }
271    }
272}
273
274/// Calls `op` if the result is [`Ok`], otherwise returns the [`Err`] value of `self`.
275///
276/// This function can be used for control flow based on `Result` values.
277///
278/// # Examples
279///
280/// ```rune
281/// fn sq_then_to_string(x) {
282///     x.checked_mul(x).ok_or("overflowed")
283/// }
284///
285/// assert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4));
286/// assert_eq!(Ok(u64::MAX).and_then(sq_then_to_string), Err("overflowed"));
287/// assert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number"));
288/// ```
289#[rune::function(instance)]
290fn and_then(this: &Result<Value, Value>, op: Function) -> Result<Result<Value, Value>, VmError> {
291    match this {
292        Ok(v) => Ok(op.call((v,))?),
293        Err(e) => Ok(Err(e.clone())),
294    }
295}
296
297/// Maps a `Result<T, E>` to `Result<U, E>` by applying a function to a
298/// contained [`Ok`] value, leaving an [`Err`] value untouched.
299///
300/// This function can be used to compose the results of two functions.
301///
302/// # Examples
303///
304/// Print the numbers on each line of a string multiplied by two.
305///
306/// ```rune
307/// let lines = ["1", "2", "3", "4"];
308/// let out = [];
309///
310/// for num in lines {
311///     out.push(i64::parse(num).map(|i| i * 2)?);
312/// }
313///
314/// assert_eq!(out, [2, 4, 6, 8]);
315/// ```
316#[rune::function(instance)]
317fn map(this: &Result<Value, Value>, then: Function) -> Result<Result<Value, Value>, VmError> {
318    match this {
319        Ok(v) => Ok(Ok(then.call((v,))?)),
320        Err(e) => Ok(Err(e.clone())),
321    }
322}
323
324/// Clone the result.
325///
326/// # Examples
327///
328/// ```rune
329/// let a = Ok(b"hello world");
330/// let b = a.clone();
331///
332/// a?.extend(b"!");
333///
334/// assert_eq!(a, Ok(b"hello world!"));
335/// assert_eq!(b, Ok(b"hello world"));
336/// ```
337#[rune::function(keep, instance, protocol = CLONE)]
338fn clone(this: &Result<Value, Value>) -> Result<Result<Value, Value>, VmError> {
339    Ok(match this {
340        Ok(ok) => Ok(ok.clone_with(&mut EnvProtocolCaller)?),
341        Err(err) => Err(err.clone_with(&mut EnvProtocolCaller)?),
342    })
343}
344
345/// Test two results for partial equality.
346///
347/// # Examples
348///
349/// ```rune
350/// assert_eq!(Ok(b"a") == Ok(b"a"), true);
351/// assert_eq!(Ok(b"a") == Ok(b"ab"), false);
352/// assert_eq!(Ok(b"ab") == Ok(b"a"), false);
353/// ```
354///
355/// Using explicit functions:
356///
357/// ```rune
358/// use std::ops::partial_eq;
359///
360/// assert_eq!(partial_eq(Ok(b"a"), Ok(b"a")), true);
361/// assert_eq!(partial_eq(Ok(b"a"), Ok(b"ab")), false);
362/// assert_eq!(partial_eq(Ok(b"ab"), Ok(b"a")), false);
363/// ```
364#[rune::function(keep, instance, protocol = PARTIAL_EQ)]
365#[inline]
366fn partial_eq(this: &Result<Value, Value>, rhs: &Result<Value, Value>) -> Result<bool, VmError> {
367    match (this, rhs) {
368        (Ok(a), Ok(b)) => Ok(Value::partial_eq(a, b)?),
369        (Err(a), Err(b)) => Ok(Value::partial_eq(a, b)?),
370        _ => Ok(false),
371    }
372}
373
374/// Test two results for total equality.
375///
376/// # Examples
377///
378/// ```rune
379/// use std::ops::eq;
380///
381/// assert_eq!(eq(Ok(b"a"), Ok(b"a")), true);
382/// assert_eq!(eq(Ok(b"a"), Ok(b"ab")), false);
383/// assert_eq!(eq(Ok(b"ab"), Ok(b"a")), false);
384/// ```
385#[rune::function(keep, instance, protocol = EQ)]
386#[inline]
387fn eq(this: &Result<Value, Value>, rhs: &Result<Value, Value>) -> Result<bool, VmError> {
388    match (this, rhs) {
389        (Ok(a), Ok(b)) => Value::eq(a, b),
390        (Err(a), Err(b)) => Value::eq(a, b),
391        _ => Ok(false),
392    }
393}
394
395/// Perform a partial ordered comparison between two results.
396///
397/// # Examples
398///
399/// ```rune
400/// assert!(Ok(b"a") < Ok(b"ab"));
401/// assert!(Ok(b"ab") > Ok(b"a"));
402/// assert!(Ok(b"a") == Ok(b"a"));
403/// ```
404///
405/// Using explicit functions:
406///
407/// ```rune
408/// use std::cmp::Ordering;
409/// use std::ops::partial_cmp;
410///
411/// assert_eq!(partial_cmp(Ok(b"a"), Ok(b"ab")), Some(Ordering::Less));
412/// assert_eq!(partial_cmp(Ok(b"ab"), Ok(b"a")), Some(Ordering::Greater));
413/// assert_eq!(partial_cmp(Ok(b"a"), Ok(b"a")), Some(Ordering::Equal));
414/// ```
415#[rune::function(keep, instance, protocol = PARTIAL_CMP)]
416#[inline]
417fn partial_cmp(
418    this: &Result<Value, Value>,
419    rhs: &Result<Value, Value>,
420) -> Result<Option<Ordering>, VmError> {
421    match (this, rhs) {
422        (Ok(a), Ok(b)) => Value::partial_cmp(a, b),
423        (Err(a), Err(b)) => Value::partial_cmp(a, b),
424        (Ok(..), Err(..)) => Ok(Some(Ordering::Greater)),
425        (Err(..), Ok(..)) => Ok(Some(Ordering::Less)),
426    }
427}
428
429/// Perform a totally ordered comparison between two results.
430///
431/// # Examples
432///
433/// ```rune
434/// use std::cmp::Ordering;
435/// use std::ops::cmp;
436///
437/// assert_eq!(cmp(Ok(b"a"), Ok(b"ab")), Ordering::Less);
438/// assert_eq!(cmp(Ok(b"ab"), Ok(b"a")), Ordering::Greater);
439/// assert_eq!(cmp(Ok(b"a"), Ok(b"a")), Ordering::Equal);
440/// ```
441#[rune::function(keep, instance, protocol = CMP)]
442#[inline]
443fn cmp(this: &Result<Value, Value>, rhs: &Result<Value, Value>) -> Result<Ordering, VmError> {
444    match (this, rhs) {
445        (Ok(a), Ok(b)) => Value::cmp(a, b),
446        (Err(a), Err(b)) => Value::cmp(a, b),
447        (Ok(..), Err(..)) => Ok(Ordering::Greater),
448        (Err(..), Ok(..)) => Ok(Ordering::Less),
449    }
450}
451
452/// Hash the result.
453///
454/// # Examples
455///
456/// ```rune
457/// use std::ops::hash;
458///
459/// let a = Ok("hello");
460/// let b = Ok("hello");
461///
462/// assert_eq!(hash(a), hash(b));
463/// ```
464#[rune::function(keep, instance, protocol = HASH)]
465fn hash(this: &Result<Value, Value>, hasher: &mut Hasher) -> Result<(), VmError> {
466    match this {
467        Ok(value) => {
468            hasher.write_u64(0);
469            value.hash(hasher)?;
470        }
471        Err(value) => {
472            hasher.write_u64(1);
473            value.hash(hasher)?;
474        }
475    }
476
477    Ok(())
478}
479
480/// Write a debug representation of a result.
481///
482/// # Examples
483///
484/// ```rune
485/// println!("{:?}", Ok("Hello"));
486/// println!("{:?}", Err("Hello"));
487/// ```
488#[rune::function(keep, instance, protocol = DEBUG_FMT)]
489#[inline]
490fn debug_fmt(this: &Result<Value, Value>, f: &mut Formatter) -> Result<(), VmError> {
491    match this {
492        Ok(value) => {
493            f.try_write_str("Ok(")?;
494            value.debug_fmt(f)?;
495            f.try_write_str(")")?;
496        }
497        Err(value) => {
498            f.try_write_str("Err(")?;
499            value.debug_fmt(f)?;
500            f.try_write_str(")")?;
501        }
502    }
503
504    Ok(())
505}
506
507/// Using [`Result`] with the try protocol.
508///
509/// # Examples
510///
511/// ```rune
512/// fn maybe_add_one(value) {
513///     Ok(value? + 1)
514/// }
515///
516/// assert_eq!(maybe_add_one(Ok(4)), Ok(5));
517/// assert_eq!(maybe_add_one(Err("not a number")), Err("not a number"));
518/// ```
519#[rune::function(keep, instance, protocol = TRY)]
520pub(crate) fn result_try(this: &Result<Value, Value>) -> Result<ControlFlow, VmError> {
521    Ok(match this {
522        Ok(value) => ControlFlow::Continue(value.clone()),
523        Err(error) => ControlFlow::Break(Value::try_from(Err(error.clone()))?),
524    })
525}