Simple, extendable and embeddable scripting language.

Overview

duckscript

duckscript SDK CLI
crates.io crates.io crates.io

downloads CI codecov license Built with cargo-make

Simple, extendable and embeddable scripting language.

Overview

Duckscript is a simple, extendable and embeddable scripting language.
The language itself has only few rules and most common language features are implemented as commands rather than part of the language itself.

Language Goals

Duckscript scripting language goals are:

  • Simple - This is probably the simplest language you will ever see.
  • Extendable - Instead of having common features such as functions and conditional blocks be a part of the language, they are actually part of the API. So they can easily be replaced/modified or you can add more 'feature' like commands on your own.
  • Embeddable - One of the main purposes of this language is to allow other libraries/executables/apps have scripting capability by embedding duckscript. Embedding is easy (for rust) and requires only few lines of code.

Installation

If you have rust, just run the following command

cargo install --force duckscript_cli

This will install duckscript script runner, the standard duckscript SDK and the duckscript CLI.
You should then have a duck executable in your ~/.cargo/bin directory.
Make sure to add ~/.cargo/bin directory to your PATH variable.

Homebrew

brew install duckscript

More details in the brew page

Binary Release

Binary releases are available in the github releases page.
The following binaries are available for each release:

  • x86_64-unknown-linux-musl
  • x86_64-apple-darwin
  • x86_64-pc-windows-msvc

Duckscript Tutorial

The following sections will teach you how to write and run duck scripts.

Hello World Example

Let's take a really simple example (all examples are located in the examples directory:

# print the text "Hello World"
echo Hello World

Running this script is done using the duck executable as follows:

duck ./examples/hello_world.ds

We will understand more and breakdown this down in the following sections.

Running the duck command without any arguments will open up the repl mode.

Commands

Commands are the basis of everything in duckscript.
Commands may execute some action (like printing "Hello World" to the console) or serve as flow control (such as functions or if/else conditions).
In order to invoke an action, simply write the action name:

echo

The basic syntax of a command line is:

[:label] [output variable =] [command [arguments]]

Passing Arguments

Commands may accept arguments, for example the command echo may accept any number of arguments and it will print all of them.
Arguments are separated with the space character.
So in the example:

# print the text "Hello World"
echo Hello World

The echo command got 2 arguments: "Hello" and "World".
If your argument contains a space, you can wrap the entire argument with the " character as follows:

# print the text "Hello World"
echo "Hello World"

In which case the echo command got only one argument: "Hello World" and prints it.
You can escape the " character using the "\" character, for example:

# print the text 'hello "world"'
echo "hello \"world\""

In the above example, the echo command got one argument: 'hello "world"' and prints it.
The "\" is also used to escape the following:

  • \n - End of line
  • \r - Carriage return
  • \t - Tab character

Storing Output

Commands may return an output which can be stored in a variable.
Variables in duckscript have no strict type.
In the following example, the set command takes one argument and stores it in the out variable.

out = set "Hello World"

Duckscript has only global scope, so once you have stored a value in a variable, you may use it anywhere in your script.

Using Variables - Binding

Stored variables can be later on used as arguments for other commands.
In order to use a variable, we need to wrap it as follows: ${variable}.

The following example uses the set command to store a value in the out variable and then prints it:

out = set "Hello World"

# This will print: "The out variable holds the value: Hello World"
echo The out variable holds the value: ${out}

# This will print: "To use the out variable just write: ${out}"
echo To use the out variable just write: \${out}

In this example, although out holds the value Hello World which contains a space, it is still considered as a single input argument to the echo command.
In the second echo command we prevented the variable name from being replaced by escaping it using the \ character.

Using Variables - Spread Binding

Spread binding provides a way to convert a variable value into multiple command arguments.
For example:

out = set "Hello World"

The out variable holds the value "Hello World".
If we were to create an array from it using the array command as follows:

list = array ${out}

The array would be of size 1 and its only entry value would be "Hello World".
So it is the same as if we wrote:

list = array "Hello World"

But what if we want to split the value to multiple parts separated by spaces?
For that we have the spread binding which is defined as follows: %{variable}.
For example:

list = array %{out}

Which would act the same as:

list = array Hello World

And now our array is of size 2 with first entry "Hello" and second entry "World".

Labels

Labels are simple textual names you can give to a specific line.
Commands like goto can then be used to make the script execution jump from its current position to the label position.
For example:

goto :good

echo error!!!!

:good echo yay!!!!

Comments

Comments are not executed and are simply in the code for documentation purposes.
A document line must start with the # character.
You can also have a comment after the command and the command will ignore it.
For example:

# This is just a comment

echo This will print # But this will not

Pre Processing

Pre processing is the phase that duckscript is parsing the script content.
It is possible to run specific commands at that phase to modify the script during the parsing phase.

The basic syntax of a pre processing command line is:

!command [arguments]

!include_files

The include_files command enables you to load script files into the position of the pre processor command.
Basically it enables you to include many scripts and generate one bigger script for runtime.
The include files command accepts any number of files and all will be loaded by the order they are defined.
For example:

# load the hello_world.ds script here
!include_files ./hello_world.ds

# load 2 scripts here. The hello_world.ds is loaded again.
!include_files ./hello_world.ds ./use_variable.ds

Important to note that the script paths included are relative to the script file including them and not to the current working directory.

!print

The print pre processing command allows to print any number of arguments, which could be useful for debugging.
In the following example, although the print command comes after the echo command, it will execute first as it is invoked in the parsing phase and not in the script execution phase which comes later:

# this will print "Hello World during script execution"
echo Hello World during script execution

# this will print "Hello World during parsing"
!print Hello World during parsing

Standard API

Duckscript is split to several modules and while the script runner does not require it, by default it will come with the standard duckscript API called the duckscript SDK.
This SDK holds the most common commands, some which execute actions (such as echo) and some which serve as flow control (such as function).
The SDK enables users to develop their scripts and have a good starting point without the need to develop the commands on their own (as that is a bit more complex).

Commands Instead Of Language Features

As mentioned before, duckscript is really simple and only has few basic rules.
In order to provide a more richer development experience, common language features such as functions and conditional blocks have been implemented as commands.
This is an example of the function command:

fn print_first_and_second_argument
    echo ${1} ${2}
    return printed
end

fn run_flow
    status = print_first_and_second_argument Hello World
    echo The printout status is: ${status}
end

run_flow

This example demonstrates how functions as a concept do not need to be part of the language and can be implemented by anyone as a command.
This also means that other developers can replace the function command with their implementation to provide additional/different functionality.

Below an example of loops using the for/in command:

values = range 1 10

for i in ${values}
    for j in ${values}
        echo i: ${i} j: ${j}
    end
end

release ${values}

Below an example of if/else command:

echo Enter Full Name:
name = read

if is_empty ${name}
    echo You did not enter any value
else
    echo Your name is: ${name}
end

value = set false
if ${value}
    echo should not be here
elseif true or false
    echo in else if but not done yet

    value = set true

    if not true and false
        echo nested if

        value = set "some text"

        if starts_with ${value} "some"
            echo after command
        else
            echo should not be here
        end
    end
else
    echo should not be here
end

Full SDK Docs

The full SDK docs can be found here

Keep in mind that the command names (such as std::Echo) can be used to invoke the commands, however for simplicity, the documentation examples uses the alias form of the commands (for example: echo).
Each command may have multiple aliases which can be used to invoke it.

Final Notes

That's It!!!!
That is all the language.
Short, simple, only few rules to follow and you mastered duckscript.

If you want to know what more you can do with it, look at the SDK docs.
If you want to know how to write your own commands or embed the duckscript runtime in your application, continue reading.

Duckscript Command Implementation Tutorial

Want to write new custom commands so you can use them in your duckscripts? great!
Hopefully the following sections will help you gain the basic knowledge on how to write them.

First of all it is important to understand that there are two types of commands:

  • Commands which execute some action like copying files, printing some text to the console or returning an environment variable.
  • Commands which provide flow control or some more complex action and require modifying the internal context in runtime.

Standard Commands

Commands are structs that must implement the Command trait.

  • They must have a name, which is used to invoke the command.
  • They optionally may have aliases which can also be used to invoke the command.
  • They should return help documentation in markdown format in order to generate SDK documentation (must for PRs to duckscript official SDK).
  • They must implement the run function which holds the command logic.

The run function accepts the command arguments (variables already replaced to actual values) and returns the command result.
The command result can be one of the following:

  • Continue(Option) - Tells the runner to continue to the next command and optionally set the output variable the given value.
  • GoTo(Option, GoToValue) - Tells the runner to jump to the requested line or label and optionally set the output variable the given value.
  • Error(String) - Returns the value 'false' and invokes the 'on_error' command if exists with the error message and instruction information.
  • Crash(String) - Tells the runner to stop the execution and return the error message.
  • Exit(Option) - Tells the runner to stop the execution and optionally set the output variable the given value.

Let's implement a simple set command which accepts a single argument and sets the output variable to that value.
And if no argument was provided, return a None which will tell the runner to delete the output variable.
Afterwards the runner should continue to the next line.
So we need to use a Continue(Option) result.
Full example:

struct SetCommand {}

impl Command for SetCommand {
    fn name(&self) -> String {
        "set".to_string()
    }

    fn run(&self, arguments: Vec<String>) -> CommandResult {
        let output = if arguments.is_empty() {
            None
        } else {
            Some(arguments[0].clone())
        };

        CommandResult::Continue(output)
    }
}

Let's implement a get_env command which pulls an environment variable value and sets the output variable with that value.
In case no input was provided we will throw an error, otherwise we will use the first input as the environment variable key.
We will return the value if exists or nothing if it does not.
Full example:

struct GetEnvCommand {
    package: String,
}

impl Command for GetEnvCommand {
    fn name(&self) -> String {
        "get_env".to_string()
    }

    fn run(&self, arguments: Vec<String>) -> CommandResult {
        if arguments.is_empty() {
            CommandResult::Error("Missing environment variable name.".to_string())
        } else {
            match env::var(&arguments[0]) {
                Ok(value) => CommandResult::Continue(Some(value)),
                Err(_) => CommandResult::Continue(None),
            }
        }
    }
}

You can look at more examples in the duckscript_sdk folder.

Context Commands

Context commands are exactly the same as standard commands except that they have access to the runtime context.
Therefore they implement the same Command trait but this time instead of implementing the run function, they need to implement the following:

  • requires_context - Must return true
  • run_with_context - The same logic you would put in the run function but now you have access to a lot more of the runtime context.

The run_with_context signature is as follows:

/// Run the instruction with access to the runtime context.
///
/// # Arguments
///
/// * `arguments` - The command arguments array
/// * `state` - Internal state which is only used by commands to store/pull data
/// * `variables` - All script variables
/// * `output_variable` - The output variable name (if defined)
/// * `instructions` - The entire list of instructions which make up the currently running script
/// * `commands` - The currently known commands
/// * `line` - The current instruction line number (global line number after including all scripts into one global script)
fn run_with_context(
    &self,
    arguments: Vec<String>,
    state: &mut HashMap<String, StateValue>,
    variables: &mut HashMap<String, String>,
    output_variable: Option<String>,
    instructions: &Vec<Instruction>,
    commands: &mut Commands,
    line: usize,
) -> CommandResult;

With access to this context you can add/remove/switch commands in runtime, store/pull internal state, add/remove/change variables and so on...

Duckscript Embedding Tutorial

Embedding duckscript is really simple and this is one of the language main goals.
The duckscript cli basically embeds duckscript so you can look at it as a reference, but basically it boils down to really few lines of code:

let mut context = Context::new();
duckscriptsdk::load(&mut context.commands)?;
runner::run_script_file(file, context)?;

That's it!
Unless you want to provide your own custom SDK, pre populate the runtime context with custom variables/state or pull information out of the context after invocation than those 3 lines of code is all you need to do.
Let's go over it line by line.

Setting Up The Context

The context holds the initial known commands, variables and state (internal objects used by commands).
Running the Context::new() simply creates a new empty context.
You can add to it any command, variable or state object you want before running the scripts.
In our example we load all default standard API commands into the new context via: duckscriptsdk::load(&mut context.commands)?;

Running The Script

After we have a context setup, we will run the script.
The runner enables to run a script text or a script file.
The following public functions are available:

/// Executes the provided script with the given context
pub fn run_script(text: &str, context: Context) -> Result<Context, ScriptError>;

/// Executes the provided script file with the given context
pub fn run_script_file(file: &str, context: Context) -> Result<Context, ScriptError>;

Editor Support

Contributing

There are many ways to contribute to duckscript, including:

  • Writing more commands and adding them to the standard SDK
  • Improving existing commands by adding more features
  • Improving the documentation
  • Opening issues with new feature requests or bugs found
  • Spreading the word :)

As for expanding the language, I personally prefer not to make it complex.
Let's try to add more language feature using commands and not changing the language itself.

See contributing guide

Release History

See Changelog

License

Developed by Sagie Gur-Ari and licensed under the Apache 2 open source license.

Comments
  • run test in win10 failed, because no have echo exe in there.

    run test in win10 failed, because no have echo exe in there.

    Describe The Bug

    run test in win10, the test case sdk::std::process::exec::mod_test::run_with_output will failed. It is because although the echo command can be used in the command line on windows, it is not actually an application like linux, but a part of cmd.exe.

    To Reproduce

    Error Stack

    The error stack trace
    

    Code Sample

    /// paste code here
    
    opened by umaYnit 13
  • Operate on a map of JSON objects with unknown structure

    Operate on a map of JSON objects with unknown structure

    Feature Description

    I can access JSON object keys/values by name through myjson.keyname but it would be nice to be able to load and parse a JSON file when I do not know the key names of the objects I am accessing... such as with this structure:

    {
      "unknown_a": {
        "status": "standard",
        "groups": [
          "a",
          "b"
        ]
      },
      "unknown_b": {
        "status": "non-standard",
        "groups": []
      }
    }
    

    Describe The Solution You'd Like

    json::Parse converts the JSON arrays into std::collections::Array, can we parse any JSON data structure as a map to be able to implement the respective std::collections::Map commands and be able to iterate over the map with std::flowcontrol::ForIn?

    Code Sample

    {
        "type_1": {
            "number": 500,
            "array": [1, 2, 3]
        },
        "type_2": {
            "number": 200,
            "array": [1, 2, 3]
        }
    }
    
    object = json_parse *json above*
    
    assert_eq ${object} [OBJECT]
    assert_eq is_map ${object}
    
    for o in ${object}
        echo ${o}.number
        echo ${o}.array[1]
    end
    

    I can work on a PR for this if something like this can fit into the scripting framework and would be invited into the std library.

    enhancement 
    opened by asvln 11
  • Include Cargo.lock in repository

    Include Cargo.lock in repository

    Please remove Cargo.lock from .gitignore and include it in the repository (or provide release source tarball with Cargo.lock included) – it’s important to get reproducible builds (not just) when packaging duckscript in a Linux distribution.

    documentation dependencies 
    opened by jirutka 10
  • Spread bindings broken with backslashes

    Spread bindings broken with backslashes

    Describe the bug It appears spread binding operator (%{}) doesn't work properly, returning an empty string even when the variable contains data that gets printed out when using the normal binding operator (${}). I was only able to reproduce this on windows again, maybe it's again some weird \ encoding behavior?

    To Reproduce

    Run the below code sample in duckscript (I went through cargo-make, making a simple reproduce task, but it probably works everywhere).

    If the patches are changed to only contain linux-like paths (e.g.all \\ are replaced with /), then the spread operator will work properly.

    Code Sample

    patches = set "C:\\Users\\roblabla\\Documents\\SunriseOS\\rust-patches\\0001-Create-workspace-remove-unneeded-deps-in-lockfile.patch C:\\Users\\roblabla\\Documents\\SunriseOS\\rust-patches\\0002-Add-sunrise.patch"
    echo ${patches}
    echo %{patches}
    
    investigation 
    opened by roblabla 7
  • Feature Request - echo Colored Text

    Feature Request - echo Colored Text

    Feature Description

    Would or is it possible to echo colored text within duckscript? So far I've tried echoing \033[2;31;43m to change the terminal color without any luck

    enhancement 
    opened by grbd 6
  • `if` command does not work with self-defined `function`

    `if` command does not work with self-defined `function`

    Describe the bug The if command doesn't recognize functions defined in the code as commands. It appears that if only works with built-in/SDK commands.

    To Reproduce The following code demonstrates the behavior:

    # The built-in command `set` is called and returns `false` to the `if`,
    # so nothing is printed.
    if set false
        echo This will not be printed
    end
    
    # The custom function is never evaluated. I think `return_bool`
    # is being treated as a string and not a command name, and
    # since a string is truthy the text is printed.
    function return_bool
        echo This will not be printed
        return ${1}
    end
    if return_bool false
        echo This will be printed
    end
    
    enhancement 
    opened by nastevens 6
  • Run commands in exec/Get stdout from eval/Add some form of command substitution

    Run commands in exec/Get stdout from eval/Add some form of command substitution

    Feature Description

    I've been trying to figure out how to get the output of ls, so I could split it into an array and do an operation on a bunch of files. I can't figure out how to do this with the current tools. I can't implement my own command cause this is for a makefile.toml (can I?). I wanted to avoid Rust for a simple task, but I guess I can't. Unless I missed something, but I poured over the documentation to no avail.

    Describe The Solution You'd Like

    Allow for capturing stdout (and stderr?) of commands. I know eval is supposed to be the command equivalent for exec, so maybe it should have properties for stdout, stderr, and exitcode? Otherwise, could it use some form of command substitution like $( ) for capturing stdout?

    Edit: Probably don't even need this right now, as I only have one file right now in that directory. But I still think it would be good if I was able to do this in a scripting language.

    question 
    opened by JonahPlusPlus 5
  • Add wildcard support to cp

    Add wildcard support to cp

    Feature Description

    Currently cp doesn't support wildcard. With wildcard support, it will make copying multiple files much easier.

    Describe The Solution You'd Like

    Say, we can an folder which contains a.exe, a.pdb, b.exe and b.pdb, and we would like to copy the exe file into a folder named bin, while pdb file into a folder named symbols.

    Currently this is what we needs to do:

    cp a.exe bin/a.exe
    cp b.exe bin/b.exe
    cp a.pdb symbols/a.pdb
    cp b.pdb symbols/b.pdb
    

    With wildcard support, it will be much easier:

    cp *.exe bin/
    cp *.pdb symbols/
    

    Code Sample

    Code sample is the same as above.

    enhancement 
    opened by r12f 5
  • Exit does not return given exit code

    Exit does not return given exit code

    Hey, While further using duckscript, I ran into a problem with the exit command.

    Describe The Bug

    As I understood it, exit exits the session returning the code supplied, but it seems as if always 0 is returned from the script execution.

    To Reproduce

    [test@ducktest]$ duck
    exit 1
    [test@ducktest]$ echo $?
    0
    

    Also happens if you run it from a file, so e.g.

    [test@ducktest]$ echo "exit 1" > test.ds && duck test.ds
    [test@ducktest]$ echo $?
    0
    
    bug 
    opened by AntonOellerer 5
  • Commands should accept empty string (

    Commands should accept empty string ("") inputs

    Describe the bug

    Empty values (""), which can be valid values, are dropped by commands.

    This causes lots of headaches, ie eq "" $value is an error, arrays can't have empty values, etc.

    opened by rivy 5
  • Using multiple backslashes results in only a single one

    Using multiple backslashes results in only a single one

    Describe The Bug

    Using multiple backslashes results in only a single one This is really annoying when trying to access files in a WSL as the path to it is: \\wsl$\Ubuntu\

    To Reproduce

    echo \\\\
    

    Result:

    \

    Expected result:

    \\

    bug 
    opened by Blightbuster 4
  • Bump suppaftp from 4.5.2 to 4.5.3

    Bump suppaftp from 4.5.2 to 4.5.3

    Bumps suppaftp from 4.5.2 to 4.5.3.

    Changelog

    Sourced from suppaftp's changelog.

    4.5.3

    Released on 27/12/2022

    • Don't use read to string from stream, but read line
    • Response body is now bytes
    • Fixed issue 24
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • glob follows symlinks recursively

    glob follows symlinks recursively

    Describe The Bug

    In a directory that has a recursive symbolic link, the duckscript glob_array command performs a cyclic recursion.

    To Reproduce

    1. Create a symbolic link that points at its parent directory
    2. Use glob_array

    Commentary

    This is a bug in glob, not duckscript, but duckscript isn't completely off the hook because the glob crate has had an issue open since 2017 (https://github.com/rust-lang/glob/issues/62), and a PR to fix it, but the crate hasn't been updated in several years. There are other glob-like crates in the ecosystem now with better options, including ones to ignore symlinks. It might be worthwhile migrating to one of them.

    opened by sffc 3
  • AUR package for duckscript

    AUR package for duckscript

    Feature Description

    Currently, cargo is the only way to install duckscript on most systems. Arch Linux has a robust packaging system and duckscript could have a package within it. This way, updating duckscript on Arch and Arch-based systems will be pretty streamlined. This would also install duckscript system-wide.

    Describe The Solution You'd Like

    The solution entails creating and submitting an AUR Package. I would be more than willing to make this contribution and to also maintain it, should the need be. Essentially, the package will always give users the latest release of duckscript.

    Code Sample

    N/A.

    opened by SwapnilKumbhar 2
  • Newline Escapes

    Newline Escapes

    Feature Description

    Currently, DuckScript appears to lack any means to split up long lines. A simple \ before a newline probably is a good yet simple solution to the problem.

    Describe The Solution You'd Like

    At the end of lines, including a \ character should tell the parser to ignore the newline and continue parsing the command on the previous line.

    Code Sample

    exec --fail-on-error nix build ".#docker-image" \
      --arg foo true \
      --arg bar ${var} \
      --arg baz "Lorem ipsum"
    
    enhancement 
    opened by enderger 3
  • --recursive flag for some `fs` commands

    --recursive flag for some `fs` commands

    Feature Description

    Sometimes it can be quite useful to operate not only on a directory but also all subdirs. Therefore, I'd like an easy way to get all files in a file tree or compare if any file in one dir is newer than another path.

    Describe The Solution You'd Like

    a recursive flag for commands like ls or is_path_newer.

    For ls the behavior is easily defined: just print all files of any subpath.

    For is_path_newer there are technically 3 different possible behaviors:

    • recursive only the one that should be newer
    • recursive only the one that should be older
    • recursive for both.

    For my use case, any of these would be fine (I just want to know if any file in the src dir is newer than the build dir), but they could also be made available as 2-3 different flags:

    • recursive-left
    • recursive-right
    • (recursive-both)

    There are probably other commands that would benefit from this as well.

    opened by ModProg 8
  • Zip/unzip command

    Zip/unzip command

    Feature Description

    I'd like to have commands to pack/unpack ZIP archives.

    I believe the ZIP format is supported nearly by everything and it would be a nice utility.

    Describe The Solution You'd Like

    The exact design of these commands and the default mode of operation might need discussion. The implementation probably can be based on the zip crate.

    Some things to consider:

    • Compression modes (perhaps deflate would be a decent default).
    • File paths (especially when making an archive: the file path inside an archive doesn't have to match the real path of the file being added). I think we have two options: either packing the files in a directory, making that directory the base for all in-archive file paths, or allowing the user to provide a map of real paths to the in-archive ones.

    Not sure whether it should cover all possible cases as that would complicate the usage by a fair bit. Based on that, my proposal is following:

    zip <archive name> <base dir path>
    

    This command would add all the files and folders in the provided base directory, and their paths in the archive would be basically relative to the base directory.

    As for unpacking, it's far easier:

    unzip <archive name> <dir>
    

    That would unpack the archive in the given directory, creating it if necessary. If some files already exist in there, the command should probably fail with an error.

    enhancement 
    opened by Red-Teapot 6
Releases(0.8.16)
Cross-platform embeddable sandboxing

Birdcage This library is still under development and not ready to be used yet. About Birdcage is a cross-platform embeddable sandboxing library allowi

Phylum 36 Dec 13, 2022
👄 The most accurate natural language detection library in the Rust ecosystem, suitable for long and short text alike

Table of Contents What does this library do? Why does this library exist? Which languages are supported? How good is it? Why is it better than other l

Peter M. Stahl 569 Jan 3, 2023
A fast, low-resource Natural Language Processing and Text Correction library written in Rust.

nlprule A fast, low-resource Natural Language Processing and Error Correction library written in Rust. nlprule implements a rule- and lookup-based app

Benjamin Minixhofer 496 Jan 8, 2023
Rust-tokenizer offers high-performance tokenizers for modern language models, including WordPiece, Byte-Pair Encoding (BPE) and Unigram (SentencePiece) models

rust-tokenizers Rust-tokenizer offers high-performance tokenizers for modern language models, including WordPiece, Byte-Pair Encoding (BPE) and Unigra

null 165 Jan 1, 2023
lingua-rs Python binding. An accurate natural language detection library, suitable for long and short text alike.

lingua-py lingua-rs Python binding. An accurate natural language detection library, suitable for long and short text alike. Installation pip install l

messense 7 Dec 30, 2022
A simple and fast linear algebra library for games and graphics

glam A simple and fast 3D math library for games and graphics. Development status glam is in beta stage. Base functionality has been implemented and t

Cameron Hart 953 Jan 3, 2023
Natural language detection library for Rust. Try demo online: https://www.greyblake.com/whatlang/

Whatlang Natural language detection for Rust with focus on simplicity and performance. Content Features Get started Documentation Supported languages

Sergey Potapov 805 Dec 28, 2022
Natural Language Processing for Rust

rs-natural Natural language processing library written in Rust. Still very much a work in progress. Basically an experiment, but hey maybe something c

Chris Tramel 211 Dec 28, 2022
Query textual streams with PromQL-like language

pq - query textual streams with PromQL Glossary Time Series - a stream of timestamped values, aka samples sharing the same metric name and, optionally

Ivan Velichko 310 Dec 23, 2022
A HDPSG-inspired symbolic natural language parser written in Rust

Treebender A symbolic natural language parsing library for Rust, inspired by HDPSG. What is this? This is a library for parsing natural or constructed

Theia Vogel 32 Dec 26, 2022
Rust-nlp is a library to use Natural Language Processing algorithm with RUST

nlp Rust-nlp Implemented algorithm Distance Levenshtein (Explanation) Jaro / Jaro-Winkler (Explanation) Phonetics Soundex (Explanation) Metaphone (Exp

Simon Paitrault 34 Dec 20, 2022
The Reactive Extensions for the Rust Programming Language

This is an implementation of reactive streams, which, at the high level, is patterned off of the interfaces and protocols defined in http://reactive-s

ReactiveX 468 Dec 20, 2022
frawk is a small programming language for writing short programs processing textual data

frawk frawk is a small programming language for writing short programs processing textual data. To a first approximation, it is an implementation of t

Eli Rosenthal 1k Jan 7, 2023
Ultra-fast, spookily accurate text summarizer that works on any language

pithy 0.1.0 - an absurdly fast, strangely accurate, summariser Quick example: pithy -f your_file_here.txt --sentences 4 --help: Print this help messa

Catherine Koshka 13 Oct 31, 2022
A sweet n' simple pastebin with syntax highlighting and no client-side code!

sweetpaste sweetpaste is a sweet n' simple pastebin server. It's completely server-side, with zero client-side code. Configuration The configuration w

Lucy 0 Sep 4, 2022
Simple NLP in Rust with Python bindings

vtext NLP in Rust with Python bindings This package aims to provide a high performance toolkit for ingesting textual data for machine learning applica

Roman Yurchak 133 Jan 3, 2023
Simple STM32F103 based glitcher FW

Airtag glitcher (Bluepill firmware) Simple glitcher firmware running on an STM32F103 on a bluepill board. See https://github.com/pd0wm/airtag-dump for

Willem Melching 27 Dec 22, 2022
Simple Data Stealer

helfsteal Simple Data Stealer Hi All, I published basic data stealer malware with Rust. FOR EDUCATIONAL PURPOSES. You can use it for Red Team operatio

Ahmet Güler 7 Jul 7, 2022
A simple OpenAI (GPT-3) client written in Rust.

A simple OpenAI (GPT-3) client written in Rust. It works by making HTTP requests to OpenAI's API and consuming the results.

Apostolos Kiraleos 3 Oct 28, 2022