Inkwell - It's a New Kind of Wrapper for Exposing LLVM (Safely)

Overview

Inkwell(s)

Crates.io Build Status codecov lines of code Join the chat at https://gitter.im/inkwell-rs/Lobby Minimum rustc 1.42

It's a New Kind of Wrapper for Exposing LLVM (Safely)

Inkwell aims to help you pen your own programming languages by safely wrapping llvm-sys. It provides a more strongly typed interface than the underlying LLVM C API so that certain types of errors can be caught at compile time instead of at LLVM's runtime. This means we are trying to replicate LLVM IR's strong typing as closely as possible. The ultimate goal is to make LLVM safer from the rust end and a bit easier to learn (via documentation) and use.

Requirements

  • Rust 1.42+
  • Rust Stable, Beta, or Nightly
  • LLVM 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, or 13.0

Usage

You'll need to point your Cargo.toml to an existing preview crate on crates.io or the master branch with a corresponding LLVM feature flag:

[dependencies]
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master", features = ["llvm12-0"] }

Supported versions:

LLVM Version Cargo Feature Flag
3.6.x llvm3-6
3.7.x llvm3-7
3.8.x llvm3-8
3.9.x llvm3-9
4.0.x llvm4-0
5.0.x llvm5-0
6.0.x llvm6-0
7.0.x llvm7-0
8.0.x llvm8-0
9.0.x llvm9-0
10.0.x llvm10-0
11.0.x llvm11-0
12.0.x llvm12-0
13.0.x llvm13-0

Please be aware that we may make breaking changes on master from time to time since we are pre-v1.0.0, in compliance with semver. Please prefer a crates.io release whenever possible!

Documentation

Documentation is automatically deployed here based on master. These docs are not yet 100% complete and only show the latest supported LLVM version due to a rustdoc issue. See #2 for more info.

Examples

Tari's llvm-sys example written in safe code1 with Inkwell:

use inkwell::OptimizationLevel;
use inkwell::builder::Builder;
use inkwell::context::Context;
use inkwell::execution_engine::{ExecutionEngine, JitFunction};
use inkwell::module::Module;
use inkwell::targets::{InitializationConfig, Target};
use std::error::Error;

/// Convenience type alias for the `sum` function.
///
/// Calling this is innately `unsafe` because there's no guarantee it doesn't
/// do `unsafe` operations internally.
type SumFunc = unsafe extern "C" fn(u64, u64, u64) -> u64;

struct CodeGen<'ctx> {
    context: &'ctx Context,
    module: Module<'ctx>,
    builder: Builder<'ctx>,
    execution_engine: ExecutionEngine<'ctx>,
}

impl<'ctx> CodeGen<'ctx> {
    fn jit_compile_sum(&self) -> Option<JitFunction<SumFunc>> {
        let i64_type = self.context.i64_type();
        let fn_type = i64_type.fn_type(&[i64_type.into(), i64_type.into(), i64_type.into()], false);
        let function = self.module.add_function("sum", fn_type, None);
        let basic_block = self.context.append_basic_block(function, "entry");

        self.builder.position_at_end(basic_block);

        let x = function.get_nth_param(0)?.into_int_value();
        let y = function.get_nth_param(1)?.into_int_value();
        let z = function.get_nth_param(2)?.into_int_value();

        let sum = self.builder.build_int_add(x, y, "sum");
        let sum = self.builder.build_int_add(sum, z, "sum");

        self.builder.build_return(Some(&sum));

        unsafe { self.execution_engine.get_function("sum").ok() }
    }
}


fn main() -> Result<(), Box<dyn Error>> {
    let context = Context::create();
    let module = context.create_module("sum");
    let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None)?;
    let codegen = CodeGen {
        context: &context,
        module,
        builder: context.create_builder(),
        execution_engine,
    };

    let sum = codegen.jit_compile_sum().ok_or("Unable to JIT compile `sum`")?;

    let x = 1u64;
    let y = 2u64;
    let z = 3u64;

    unsafe {
        println!("{} + {} + {} = {}", x, y, z, sum.call(x, y, z));
        assert_eq!(sum.call(x, y, z), x + y + z);
    }

    Ok(())
}

1 There are two uses of unsafe in this example because the actual act of compiling and executing code on the fly is innately unsafe. For one, there is no way of verifying we are calling get_function() with the right function signature. It is also unsafe to call the function we get because there's no guarantee the code itself doesn't do unsafe things internally (the same reason you need unsafe when calling into C).

LLVM's Kaleidoscope Tutorial

Can be found in the examples directory.

Alternative Crate(s)

Contributing

Check out our Contributing Guide

Comments
  • Publish inkwell to crates.io

    Publish inkwell to crates.io

    My project (Solang) depends on inkwell. I cannot publish to crates, since there is no version of inkwell on crates.io.

    Would it be possible to publish inkwell to crates.io, following the llvm-sys.rs versioning scheme? So version 90.minor.patch is llvm 9, etc.

    Thank you

    opened by seanyoung 24
  • Add support for LLVM 8

    Add support for LLVM 8

    Description

    There are two main commits here:

    • First, as per the PR title, this adds support for LLVM 8, or more specifically, adds the requisite feature and updates to llvm-sys version 80.0
    • Second, a refactoring of the llvm_versions procedural macro that adds support for single versions in addition to ranges, and also provides a cleaner path for future extensibility, as well as better error reporting. One such future improvement may be to change the syntax from X.Y => X.Y to X.Y..X.Y and X.Y..=X.Y to allow for both inclusive and exclusive ranges, whereas right now only inclusive ranges are possible.

    Related Issue

    There isn't one, but presumably LLVM 8 support is desired, and I was making the changes on my fork anyway for use in my own project, so why not share :)

    How This Has Been Tested

    So far I've only made sure that the code compiles and that the test suite passes successfully. I'll be working with the new version heavily in the coming days though, so any bugs that surface I will certainly be implementing fixes for and upstreaming here. For now though, I'm not aware of any breakages.

    NOTE: I'm compiling on macOS Mojave, using llvm-sys 80.1.0, against a copy of LLVM that I have built (using the release80 branch). I have not yet tested on other architectures or operating systems. I also compiled using both stable and nighly. toolchains.

    The actual changes required were pretty minimal from what I've seen so far, one set of soft deprecations (LLVM{Has,Set}UnnamedAddr => LLVM{Get,Set}UnnamedAddress), some compiler warnings, and one new addition, the LLVMFNeg opcode was added to the LLVMOpcode enum.

    Option<Breaking Changes>

    None that I'm aware of

    Checklist

    opened by bitwalker 23
  • Provide safe function wrappers

    Provide safe function wrappers

    Description

    This tries to address concerns raised in #56 by:

    1. Removing implicit Deref to the underlying function pointer that could allow it to accidentally outlive the owning execution engine.
    2. Provides function Symbol::call which guarantees that (a) backing storage will be alive as long as it's required for calling and (b) preserves unsafety for the public interface. This is done at the cost of less convenient invocation syntax (symbol.call(a,b,c,...) instead of symbol(a,b,c,...)).

    Related Issue

    #56, also an earlier issue #5.

    How This Has Been Tested

    cargo test with corresponding modifications.

    Option<Breaking Changes>

    Unfortunately, this is a breaking change for pretty much any existing code using Inkwell for JIT compilation, but I believe the added safety is worth it. It could be made non-breaking if either Fn traits on custom types or existential types were stabilised, but, unfortunately, neither is at the moment.

    Checklist

    opened by RReverser 23
  • impl Default for AddressSpace to make future changes easier

    impl Default for AddressSpace to make future changes easier

    in #383 it came up that the current representation of an address space is not entirely correct. To make changes to that type easier, and because usually "Generic" is the address space that users want, implementing and using the default instance means that even if we change the representation of address spaces, this would not actually be noticeable by users.

    Description

    Related Issue

    How This Has Been Tested

    <Breaking Changes>

    There specifically are no breaking changes in the PR

    Checklist

    opened by folkertdev 18
  • (master) Update to 2018 edition

    (master) Update to 2018 edition

    Description

    Update to 2018 edition for master branch

    Related Issue

    #54

    How This Has Been Tested

    • [x] cargo run --example kaleidoscope --no-default-features --features "llvm7-0"
    • [x] cargo test --no-default-features --features "llvm7-0"

    Other branch need more work.

    Option<Breaking Changes>

    minimum rust version change to 1.31

    Checklist

    opened by meteor-lsw 18
  • Should support multiple LLVM-sys versions

    Should support multiple LLVM-sys versions

    Probably by feature toggle, and conditional compilation. Either default to latest or require a feature to be selected (if possible)

    • [x] v3.6 (Initial support, usable)
    • [x] v3.6 (Version specific features)
    • [x] v3.7 (Initial support, usable)
    • [x] v3.7 (Version specific features)
    • [x] v3.8 (Initial support, usable)
    • [x] v3.8 (Version specific features)
    • [x] v3.9 (Initial support, usable)
    • [ ] v3.9 (Version specific features)
    • [x] v4.0 (Initial support, usable)
    • [ ] v4.0 (Version specific features)
    • [x] v5.0 (Initial support, usable)
    • [ ] v5.0 (Version specific features)
    • [x] v6.0 (Initial support, usable)
    • [ ] v6.0 (Version specific features)
    • [x] v7.0 (Initial support, usable)
    • [ ] v7.0 (Version specific features)
    • [x] v8.0 (Initial support, usable)
    • [ ] v8.0 (Version specific features)
    • [x] v9.0 (Initial support, usable)
    • [ ] v9.0 (Version specific features)
    • [x] v10.0 (Initial support, usable)
    • [ ] v10.0 (Version specific features)
    enhancement help wanted documentation 
    opened by TheDan64 18
  • Look into ways get_function_address could safely return a function

    Look into ways get_function_address could safely return a function

    Currently it returns an address value pointer, which is in itself safe - but to actually use it, the user needs to unsafely transmute it into a rust extern "C" function. I'm wondering if this could be accomplished under the hood by "deserializing" the function's FunctionType (which has all of the needed type info) into rust types. Maybe writing a Serde plugin could help when it comes to complex types like StructType & PointerType.

    Will probably need to account for edge cases - is VoidType deserializable? If so, would that just be () and is that ever useful? Is *() / &() valid in rust? Etc

    enhancement help wanted 
    opened by TheDan64 16
  • Add API for the ORCv2 execution engine

    Add API for the ORCv2 execution engine

    Description

    This PR aims to add the ability to safely interact with the ORCv2 execution engine. The new orc2 module houses all the new structs and functions. The orc2 feature is automatically enabled when the llvm version is above 11.0. I wrote the lljit example to demonstrate the new execution engine.

    Related Issue

    #179

    How This Has Been Tested

    LLVM version: 13.0.0 I tested the new module with the new lljit example. To verify that the memory management is working out I used valgrind. I wrote some doc tests.

    Checklist

    opened by leifhelm 15
  • Add method to get type by its name

    Add method to get type by its name

    Added context.get_type("name") method

    Description

    Added new method with documentation and tests to context. It uses LLVMGetTypeByName2 from llvm_sys, which was missing in inkwell.

    Related Issue

    Related to my question: #367

    How This Has Been Tested

    Test when type is found and when not found.

    Checklist

    opened by gavrilikhin-d 14
  • Extern functions are not detected by Kaleidoscope JIT

    Extern functions are not detected by Kaleidoscope JIT

    Describe the Bug As stated in the comment extern functions defined in Rust code are not detected by Kaleidoscope JIT.

    To Reproduce

    1. Run Kaleidoscope REPL.
    2. Type extern printd(x)
    3. Type printd(10)
    4. Function returns NaN

    Expected Behavior printd function should have returned passed value and printed it.

    LLVM Version (please complete the following information):

    • LLVM Version: 7.0.1
    • Inkwell Branch Used: llvm7-0

    Desktop (please complete the following information):

    • OS: OS X

    Additional Context After a bit of investigation, it seems that there are a couple of problems here:

    1. rustc will mangle the names of those function unless #[no_mangle] attribute is applied.
    2. Unless those functions are used in the Rust code, the compiler will remove them. To avoid this they should be called somewhere or put into a static array with #[used] attribute like here.
    3. Currently, body that returns NaN is set for extern functions. This causes that functions that are defined in Rust are being overridden by those that return NaN (strangely, but functions like sin and cos are not being overridden). It seems that if we got extern definition, we should not attach any body to it.

    I kinda fixed these issues in my fork, but it will segfault if extern function, that is not actually defined, is called. I'm not sure what is desired behavior here. Let me know what do you think about this.

    bug 
    opened by OlegTheCat 14
  • Support llvm-15 for inkwell

    Support llvm-15 for inkwell

    Description

    Added llvm-15 support https://github.com/TheDan64/inkwell/issues/359

    Issues

    Still has build errors.

    argo build
       Compiling inkwell v0.1.0 (/run/media/inkwell)
    error: One of the LLVM feature flags must be provided: llvm4-0 llvm5-0 llvm6-0 llvm7-0 llvm8-0 llvm9-0 llvm10-0 llvm11-0 llvm12-0 llvm13-0 llvm14-0 llvm15-0 
       --> src/lib.rs:97:9
        |
    97  |         compile_error!(concat!("One of the LLVM feature flags must be provided: ", $($all, " "),*));
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...
    108 | assert_unique_used_features! {"llvm4-0", "llvm5-0", "llvm6-0", "llvm7-0", "llvm8-0", "llvm9-0", "llvm10-0", "llvm11-0", "llvm12-0", "llvm13-0", "llvm14-0", "llvm15-0"}
        | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- in this macro invocation
        |
        = note: this error originates in the macro `assert_used_features` which comes from the expansion of the macro `assert_unique_used_features` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    error[E0433]: failed to resolve: use of undeclared crate or module `llvm_sys`
     --> src/support/error_handling.rs:4:5
      |
    4 | use llvm_sys::core::{LLVMGetDiagInfoDescription, LLVMGetDiagInfoSeverity};
      |     ^^^^^^^^ use of undeclared crate or module `llvm_sys`
    
    opened by aditya-solana 13
  • Segfault when calling native function with structure return with jit engine

    Segfault when calling native function with structure return with jit engine

    Describe the Bug Segfault when calling native function with structure return in jit engine

    To Reproduce

    use inkwell::targets::{InitializationConfig, Target};
    use inkwell::context::Context;
    use inkwell::OptimizationLevel;
    
    #[repr(C)]
    struct Result{
        value: u64,
        flag: bool,
    }
    
    #[no_mangle]
    extern fn return_struct() -> Result{
        Result { value: 2, flag: true }
    }
    
    Target::initialize_native(&InitializationConfig::default()).unwrap();
    
    let context = Context::create();
    let module = context.create_module("test");
    let builder = context.create_builder();
    let ee = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
    
    let i64t = context.i64_type();
    let bt = context.bool_type();
    let ft = context.f64_type();
    let fnt = i64t.fn_type(&[], false);
    
    let f = module.add_function("test_fn", fnt, None);
    let b = context.append_basic_block(f, "entry");
    
    builder.position_at_end(b);
    
    let func_ty = context.struct_type(&[i64t.into(), bt.into()], false);
    let extf = module.add_function("struct_fn", func_ty.fn_type(&[], false), None);
    ee.add_global_mapping(&extf, return_struct as usize);
    
    let call_site_value = builder.build_call(extf, &[], "retv");
    let retv = call_site_value.try_as_basic_value().left().unwrap().into_struct_value();
    
    let value = builder.build_extract_value(retv, 0, "").unwrap().into_int_value();
    let flag = builder.build_extract_value(retv, 1, "").unwrap().into_int_value();
    
    // do something...
    
    builder.build_return(Some(&value));
    
    
    unsafe{
        let value = ee.run_function(f, &[]).as_int(false);
        assert!(value == 2)
    }
    

    Expected Behavior return without error

    LLVM Version (please complete the following information):

    • LLVM Version: 13.0.0
    • Inkwell Branch Used: llvm13-0

    Desktop (please complete the following information):

    • OS: Windows 10

    Additional Context CPU: i7-1165G7

    question 
    opened by YC-Lammy 2
  • Support llvm-sys 150.x.x

    Support llvm-sys 150.x.x

    Updates

    1. Support the opaque pointers and all related functions.
    2. Guard the LLVMConst* function family.
    3. Guard some optimization passes, including those for coroutines.
    4. Update the AtomicRMWBinOp enum.
    5. Add conditional compilation clauses for some low-hanging functions.
    6. Fix the AddressSpace enum and make it more generic (breaking).
    7. Add functions for parsing LLVM IR from the memory and files.
    8. Add the function for parsing command line options.
    9. The bitcast operation now returns AnyType to support function pointer casts.
    10. Some minor fixes and improvements.
    11. Updated some dependencies.

    Notes

    1. I decided not to continue nesting in the functions which require opaque pointers, but instead implement another set of function with the suffix _2. It's not a perfect solution, but the alternative one would be worse from my point of view.
    2. The PR wasn't yet sanitized with clippy, and some tests are probable missing. Let's discuss. Honestly I feel like the project hasn't been sanitized in multiple previous PRs as well.

    Related issues

    https://github.com/TheDan64/inkwell/issues/359

    Supersedes this PR

    opened by hedgar2017 49
  • Opaque pointers

    Opaque pointers

    Is your feature request related to a problem? Please describe. LLVM is moving towards opaque pointers. In LLVM 16 non-opaque pointers are forbidden. It's probably worth to start implementing optional support for them now.

    Describe the solution you'd like Add new type OpaquePointerType

    Describe possible drawbacks to your solution None, except more work. Opaque pointers are inevitable

    Describe alternatives you've considered Add Context::use_opaque_pointers function, as LLVM did.

    feature request 
    opened by gavrilikhin-d 0
  • Add `fn_type` for type enums

    Add `fn_type` for type enums

    Description

    Adds implementation of fn_type for type enums, for convenience

    Related Issue

    #380

    How This Has Been Tested

    Run doc tests and cargo test --features llvm14-0

    Checklist

    opened by gavrilikhin-d 0
  • Add `fn_type` to enums

    Add `fn_type` to enums

    Is your feature request related to a problem? Please describe.

    My compilers dynamically lower types to inkwell's:

    pub fn lower_type(&self, ty: &mir::Type) -> inkwell::types::BasicTypeEnum;
    ``
    
    Later, it create function with such lowered return type
    ```rs
    self.lower_type(ty).fn_type(params, false) // Not implemented
    

    This most obvious approach doesn't work.

    Describe the solution you'd like I'd like BasicTypeEnum, BasicMetadataTypeEnum, AnyTypeEnum to implement:

    pub fn fn_type(self, param_types: &[BasicMetadataTypeEnum<'ctx>], is_var_args: bool) -> FunctionType<'ctx>
    

    Types from BasicTypeEnum may always be used as return type, yet I'm not sure about MetadataType and FunctionType.

    Probably, BasicMetadataTypeEnum and AnyTypeEnum must change signature to:

    pub fn fn_type(self, param_types: &[BasicMetadataTypeEnum<'ctx>], is_var_args: bool) -> Result<FunctionType<'ctx>, ()>
    
    opened by gavrilikhin-d 0
  • Error handling for `ExecutionEngine`

    Error handling for `ExecutionEngine`

    Is your feature request related to a problem? Please describe.

    I have been following the Kaleidoscope tutorial. But if I declare a random function and then call it, the process just exit without error messages.

    extern f();
    f(); # this will crash the process.
    

    However, if I declare sin, the function is actually executed correctly.

    extern sin(x);
    sin(1); # this returns 0.8414709848078965
    

    I execute the top-level function through execution_engine.run_function(function, args);, but run_function does not return an error when the external function cannot be resolved.

    So I want to check if the external function is actually exists before run_function in case a user randomly declares a non-exist function and calls it but receives no error messages, making the user confused.

    Describe the solution you'd like

    I want the execution engine to return an error result when it decides that there are some irresolvable functions in the module.

    Describe possible drawbacks to your solution

    Probably won't affect other components since the execution engine can make a new method called run_function_with_result or something to not change the existing run_function method.

    Describe alternatives you've considered

    There can be a method of execution engines that just checks/verifies all the declarations.

    Additional context

    My JIT logic is implemented here: https://github.com/Banyc/kaleidoscope/blob/master/src/jit.rs.

    feature request 
    opened by Banyc 1
Owner
Daniel Kolsoi
Software Engineer with a focus in Rust & Python
Daniel Kolsoi
Objective-C Runtime bindings and wrapper for Rust.

Objective-C Runtime bindings and wrapper for Rust. Documentation: http://ssheldon.github.io/rust-objc/objc/ Crate: https://crates.io/crates/objc Messa

Steven Sheldon 336 Jan 2, 2023
Javascript wrapper bindings for diamond types

Diamond JS wrapper library This is a javascript / WASM wrapper around diamond types. This code is currently experimental WIP. Do not trust this for an

Seph Gentle 14 Jun 16, 2022
Unstable wrapper API for winapi's Console Functions

maulingmonkey-console-winapi-wrappers Unstable wrapper API for winapi's Console Functions Quickstart # Cargo.toml [dependencies] maulingmonkey-console

null 3 Nov 26, 2021
libnotcurses-sys is a low-level Rust wrapper for the notcurses C library

libnotcurses-sys is a low-level Rust wrapper for the notcurses C library This library is built with several layers of zero-overhead abstractions over

nick black 29 Nov 26, 2022
dm-jitaux is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle!

dm-jitaux is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle (such as rewriting/refactroing your DM code).

SS220 20 Dec 13, 2022
LLVM-CBE is a C-backend for LLVM, i.e. a tool that turns LLVM bitcode 1 into C

LLVM-CBE is a C-backend for LLVM, i.e. a tool that turns LLVM bitcode 1 into C. It requires to be built near LLVM, which was found to be so heavy dependency that shipping it as Cargo crate would be absurd.

Dmitrii - Demenev 2 May 26, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
More beautiful HTML reports for llvm-cov/cargo-llvm-cov

?? llvm-cov-pretty More beautiful HTML reports for llvm-cov (cargo-llvm-cov specifically). Dark theme support (switches automatically based on your br

Dominik Nakamura 13 Jun 26, 2023
A new kind of terminal

notty - not a typewriter notty is a virtual terminal like xterm, gnome-vte, sh, or rxvt. Unlike these programs, notty is not intended to emulate a DEC

Saoirse Shipwreckt 2.2k Jan 6, 2023
CLI utility to move (or rename) your files to a new location and redirect all of its symbolic links, to the new path

Move Links CLI utility to move (or rename) your files to a new location and redirect all of its symbolic links, to the new path (or name). Usage execu

Ben Mefteh 18 May 22, 2022
Just in time Oxidation. A little experimentation with inkwell and copy-and-patch compilation

Experimental Copy-and-Patch compiler backend written in Rust This is supposed to become an experimental compiler backend based on Copy and Patch to be

Michael Zinsmeister 4 Feb 27, 2024
REST API server that abstracts the need to write CRUD methods by exposing a standardized API to interact with a Postgres database

Basiliq Exposing a Postgres database via a REST API that follows the JSON:API specs. All in all, a tasty API. What is Basiliq Quickstart Ready to use

Basiliq 54 Apr 21, 2022
Exposing MPRIS V2.1 D-Bus interface for mpd

mpdris2-rs A lightweight implementation of MPD to D-Bus bridge, which exposes MPD player and playlist information onto MPRIS2 interface so other progr

Leo Shen 5 Nov 21, 2022
A command-line tool for exposing a wrapped program's standard IO using WebSockets/SSE

cmdpiped cmdpiped is a command-line tool for exposing a wrapped cli program's standard IO to WebSockets/SSE Installation Ready to use Binaries are ava

Geoffrey Mureithi 10 Nov 11, 2022
reth-indexer reads directly from the reth db and indexes the data into a postgres database all decoded with a simple config file and no extra setup alongside exposing a API ready to query the data.

reth-indexer reth-indexer reads directly from the reth db and indexes the data into a postgres database all decoded with a simple config file and no e

Josh Stevens 306 Jul 12, 2023
Simple library to host lv2 plugins. Is not meant to support any kind of GUI.

lv2-host-minimal Simple library to host lv2 plugins. Is not meant to support any kind of GUI. Host fx plugins (audio in, audio out) Set parameters Hos

Cody Bloemhard 11 Aug 31, 2022
Make a PDF file by writing kind of like HTML and CSS.

markup-pdf-rs The Rust library for making a PDF files by writing kind of like HTML and CSS. Inspired by Satori and React-pdf. This library makes a PDF

null 9 Jan 10, 2023
Api testing tool made with rust to use for api developement (Kind of Tui)

Api testing tool made with rust to use for api developement (Kind of Tui) This Rust project provides a simple yet powerful tool for making HTTP reques

Kythonlk 3 Feb 14, 2024
Costless typed identifiers backed by UUID, with kind readable in serialized versions

Why kind ? With kind, you use typed identifiers in Rust, with no overhead over Uuid have the type be human readable and obvious in JSON and any export

Wingback 67 Mar 24, 2024
Hatch new projects like a chick coming out of its egg

?? Cargo Hatch Hatch new projects like a chick coming out of its egg. Cargo hatch is a cargo init/cargo new on steroids, allowing complex templates th

Dominik Nakamura 6 Nov 2, 2022