vyder_std 0.3.4

Standard library for vyder.
Documentation
//! Various functions to print to stdout and format strings.
//!
//! Available under the name `std-fmt`.

use std::process::ExitCode;

use vyder::{values, Error, ExpectArity, Module, Span, Value, ValueResult};

/// Formats the argument according to `std-fmt.format` and prints the output to stdout.
pub fn print(
    arguments: &[ValueResult],
    span: Span,
) -> Result<(ValueResult, Option<ExitCode>), Error> {
    let (out, _) = format(arguments, span.clone())?;
    print!("{}", out);
    Ok((Value::new_ok_value(values::Nil.into(), span), None))
}

/// Formats the argument according to `std-fmt.format` and prints the output to stdout with a newline at the end.
pub fn println(
    arguments: &[ValueResult],
    span: Span,
) -> Result<(ValueResult, Option<ExitCode>), Error> {
    print(arguments, span.clone())?;
    println!();
    Ok((Value::new_ok_value(values::Nil.into(), span), None))
}

/// Formats the given string with the next arguments.
///
/// The first argument is the template. All following arguments are placed into the template at each "{}".
///
/// Example: `format("Hello, {}!", "World") // -> Hello, World!`
pub fn format(
    arguments: &[ValueResult],
    span: Span,
) -> Result<(ValueResult, Option<ExitCode>), Error> {
    let (format_string, arguments) = arguments.to_vec().expect_min::<1>(&span)?;
    let mut format_string = format_string[0]
        .clone()
        .expect_non_error()?
        .value
        .to_string();

    for argument in arguments {
        format_string = format_string.replacen("{}", &argument.to_string(), 1);
    }

    Ok((
        Value::new_ok_value(
            values::Str {
                value: format_string,
            }
            .into(),
            span,
        ),
        None,
    ))
}

pub fn get_module() -> Module {
    Module::builder()
        .function("print", print, false)
        .function("println", println, false)
        .function("format", format, false)
        .build()
}