An Async SDR Runtime for Heterogeneous Architectures

Related tags

Database FutureSDR
Overview

FutureSDR

An experimental asynchronous SDR runtime for heterogeneous architectures that is:

  • Extensible: custom buffers (supporting accelerators like GPUs and FPGAs) and custom schedulers (optimized for your application).

  • Asynchronous: solving long-standing issues around IO, blocking, and timers.

  • Portable: Linux, Windows, Mac, WASM, Android, and prime support for embedded platforms through a REST API and web-based GUIs.

  • Fast: SDR go brrr!

Crates.io Apache 2.0 licensed Build Status

Website | Guides | API Docs | Chat

Overview

FutureSDR supports Blocks with synchronous or asynchronous implementations for stream-based or message-based data processing. Blocks can be combined to a Flowgraph and launched on a Runtime that is driven by a Scheduler.

  • Single and multi-threaded schedulers, including examples for application-specific implementations.
  • Portable GPU acceleration using the Vulkan API (supports Linux, Windows, Android, ...).
  • User space DMA driver for Xilinx Zynq to interface FPGAs.

Development

Since FutureSDR is in an early state of development, it is likely that SDR applications will require changes to the runtime. We, therefore, do not recommend to add it as a dependency in a separate project but to clone the repository and implement the application as binary, example, or sub-crate.

Example

An example flowgraph with a periodic message source, sending five messages to a sink:

use anyhow::Result;
use std::time::Duration;

use futuresdr::blocks::MessageSink;
use futuresdr::blocks::MessageSource;
use futuresdr::runtime::Flowgraph;
use futuresdr::runtime::Pmt;
use futuresdr::runtime::Runtime;

fn main() -> Result<()> {
    let mut fg = Flowgraph::new();

    let src = fg.add_block(MessageSource::new(Pmt::Null, Duration::from_secs(1), Some(5)));
    let snk = fg.add_block(MessageSink::new());

    fg.connect_message(src, "out", snk, "in")?;

    Runtime::new().run(fg)?;

    Ok(())
}

Contributing

Contributions are very welcome. Please see the (work-in-progress) contributing guide for more information. If you develop larger features or work on major changes with the main intention to submit them upstream, it would be great, if you could announce them in advance.

Conduct

The FutureSDR project adheres to the Rust Code of Conduct. It describes the minimum behavior expected from all contributors.

License

This project is licensed under the Apache 2.0 license.

Using this license is in contrast to the large majority of Open Source SDR applications and frameworks, which are mostly AGLP, LGPL, or GPL. In a nutshell, this means that there is no money to be made from relicensing the project for commercial use, since this is already allowed by Apache 2.0. Furthermore, companies can use (parts of) the project and integrate (adapted) versions in commercial products without releasing the source or contributing back to the project.

The main motivation for this license is that

  • it better fits the Rust ecosystem
  • it eases adoption; one can use (parts of) the code with close to no strings attached
  • using Open Source and not contributing back (for the time being) seems better than not using Open Source at all

Contributions

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in FutureSDR, shall be licensed as Apache 2.0, without any additional terms or conditions.

Comments
  • Document required dependencies

    Document required dependencies

    On different operating systems different dependencies are required to make FutureSDR run smoothly with common SDR hardware.

    Compiling the FutureSDR examples on Windows e.g. fails when compiling sopaysdr-sys 0.7.3: pkg_config: Could not run "pkg-config" "--libs" "--cflags" "SoapySDR" "SoapySDR >= 0.6.0" Most likely, you need to install a pkg-config package for your OS.

    or:

    [INFO] [UHD] Win32; Microsoft Visual C++ version 14.2; Boost_107500; UHD_4.0.0.HEAD-0-g90ce6062 Found Rafael Micro R820T/2 tuner FutureSDR: ERROR - SoapySDR::Device::enumerate(sdrplay) sdrplay_api_Open() failed FutureSDR: INFO - Using format CF32.

    The Readme.md should contain some information on the required dependencies e.g.:

    Dependencies for Compiling on Microsoft Windows

    The following dependencies are required to compile the FutureSDR examples on Windows:

    • PhotosSDR: https://downloads.myriadrf.org/builds/PothosSDR/
    • LLVM Stable: https://github.com/llvm/llvm-project/releases
    • SDRuno: https://www.sdrplay.com/sdruno/

    Always select the "Add to PATH variable option in the installers", so the required libraries and binaries are found when compiling FutureSDR programs. To avoid performance issues and warnings like FutureSDR: WARN - SoapyVOLKConverters: no VOLK config file found. Run volk_profile for best performance. please run: volk_profile on your commandline.

    Dependencies for Compiling on Linux

    ...

    Dependencies for Compiling on macOS

    ...

    Note:

    These dependencies might change over time and should constantly be updated. It would be best to keep the dependencies to a minimum and choose the most slim packages which fulfill the minimum requirements.

    opened by ratzrattillo 14
  • Let compiler infer types and ports in fg.connect()

    Let compiler infer types and ports in fg.connect()

    Hey,

    I am new to Rust, so some of the things I am saying may be wrong, or technically impossible. But looking at the example in your README I was a bit surprised to see

    fg.connect_message(src, "out", snk, "in")?;
    

    because it struck me as a bit "outdated" and error-prone. I would have expected more something like

    fg.connect(src.out, snk.in)?;
    
    1. Not using strings as port-names, but instead struct fields, which allows us to catch more errors during compile time.
    2. This idea is a bit out there, but ports could be generics for their signal type, e.g. StreamPort<Complex<f32>>. This allows the compiler to even catch connection type errors and maybe even infer all connection types just from the output type of the first block?
    3. And because a field has a type (e.g. StreamPort vs MessagePort), we can infer what kind of connection we are building, so no need for connect_*() but one connect() for all port types.

    Does that make sense, and would that work? As I said, I am new to Rust so my thinking may be wrong here...

    opened by nils-werner 10
  • AudioSink add complex input or multiple taps

    AudioSink add complex input or multiple taps

    When using the AudioSink block with two channels, i would expect the block to have two input taps (e.g. one for the left and one for the right channel). @loic-fejoz suggested two have either one tap per channel, or one tap accepting a Complex number as input.

    Currently the AudioSink in blocks/audio/audio_sink.rs:40 creates the stream with a hardcoded size of 4 Bytes per sample:

    StreamIoBuilder::new().add_input("in", 4).build(),

    To play an audio file with only one channel (like the rick.mp3 example) on a windows PC, which in many cases only show an audio output device with two channels, hacks like this have to be done:

    ` use cpal::traits::{DeviceTrait, HostTrait}; use futuresdr::anyhow::Result; use futuresdr::blocks::ApplyIntoIter; use futuresdr::blocks::audio::AudioSink; use futuresdr::blocks::audio::FileSource; use futuresdr::runtime::{Flowgraph, Runtime};

    fn main() -> Result<()> {

    let host = cpal::default_host();
    let audio_device = host.default_output_device().expect("no output device available");
    println!("Device name: {}", audio_device.name().unwrap());
    let supported_configs_range = audio_device.supported_output_configs().expect("error while querying configs");
    for format in supported_configs_range {
        println!("Sample Rate: Min: {:?}, Max: {:?}", format.min_sample_rate(), format.max_sample_rate());
        println!("Channels: {}", format.channels());
        println!("SampleFormat: {:?}", format.sample_format());
    }
    
    let filename = "rick.mp3";
    let mut fg = Flowgraph::new();
    
    let src = FileSource::new(filename);
    let inner = src.as_async::<FileSource>().unwrap();
    
    fn tuple(s: &f32) -> Vec<f32> {
        let mut vec = Vec::with_capacity(2);
        vec.push(*s); // L
        vec.push(*s); // R
        return vec;
    }
    let custom = ApplyIntoIter::<f32, Vec<f32>>::new(tuple);
    let snk = AudioSink::new(inner.sample_rate(), 2); // inner.channels()
    
    println!("File: {}, Sample Rate: {}, Channels: {}", filename, inner.sample_rate(), inner.channels());
    
    let src = fg.add_block(src);
    let custom = fg.add_block(custom);
    let snk = fg.add_block(snk);
    
    fg.connect_stream(src, "out", custom, "in")?;
    fg.connect_stream(custom, "out", snk, "in")?;
    
    let rt = Runtime::new();
    rt.run(fg).unwrap();
    
    Ok(())
    

    } `

    Thanks to @loic-fejoz for providing the sample.

    opened by ratzrattillo 8
  • Produce More Output

    Produce More Output

    I'm working on a FIR filter, and need the ability to produce more output than the length of the output slice. The pattern seems to be:

            let i = sio.input(0).slice::<f32>();
            let o = sio.output(0).slice::<f32>();
    
            let n = cmp::min(i.len(), o.len());
    
    ... do work ...
    
            sio.output(0).produce(n);
    

    Then only work on n pieces of input/output. However, given interpolation for the FIR filter, it might produce more output than input. If I had say n*2 output, how can I make that work?

    From my understanding of the code, there is no interface to do that.

    opened by wspeirs 8
  • Do not return an error when flowgraph was terminated exteranlly.

    Do not return an error when flowgraph was terminated exteranlly.

    There is currently no differentiation between termination because of a block error and external termination of the flowgraph through the flowgraph handle. In both cases the flowgraph task returns an Err("Flowgraph was terminated"). While this is fine when a block failed, we should probably try to shutdown gracefully in case of external termination. Maybe we should introduce Kill (in case of block error) and Shutdown (from external). In the latter case, the flowgraph task should succeed. See this example: https://github.com/samcarey/drop_block_test/blob/main/src/main.rs#L20

    opened by bastibl 7
  • Two different crates trying to link different versions of the clang native library

    Two different crates trying to link different versions of the clang native library

    When opening the FutureSDR repo with VS Code with the rust-analyzer extension installed, there are two persistent error pop-ups:

    image

    From looking at the logs, this appears to be the result of the rust-analyzer back-end running the command cargo check --workspace. Running the same command from the command line shows the problem:

    PS C:\Users\jas\Develop\FutureSDR> cargo check --workspace
    error: multiple packages link to native library `clang`, but a native library can be linked only once
    
    package `clang-sys v0.21.2`
        ... which satisfies dependency `clang-sys = "^0.21.0"` (locked to 0.21.2) of package `bindgen v0.32.3`
        ... which satisfies dependency `bindgen = "^0.32.3"` (locked to 0.32.3) of package `lttng-ust-generate v0.1.1`
        ... which satisfies dependency `lttng-ust-generate = "^0.1.1"` (locked to 0.1.1) of package `futuresdr v0.0.19 (C:\Users\jas\Develop\FutureSDR)`
        ... which satisfies path dependency `futuresdr` (locked to 0.0.19) of package `androidfs v0.1.0 (C:\Users\jas\Develop\FutureSDR\examples\android)`
    links to native library `clang`
    
    package `clang-sys v1.3.3`
        ... which satisfies dependency `clang-sys = "^1"` (locked to 1.3.3) of package `bindgen v0.57.0`
        ... which satisfies dependency `bindgen = "^0.57.0"` (locked to 0.57.0) of package `soapysdr-sys v0.7.3`
        ... which satisfies dependency `soapysdr-sys = "^0.7.3"` (locked to 0.7.3) of package `soapysdr v0.3.2`
        ... which satisfies dependency `soapysdr = "^0.3.1"` (locked to 0.3.2) of package `futuresdr v0.0.19 (C:\Users\jas\Develop\FutureSDR)`
        ... which satisfies path dependency `futuresdr` (locked to 0.0.19) of package `androidfs v0.1.0 (C:\Users\jas\Develop\FutureSDR\examples\android)`
    also links to native library `clang`
    

    I see this on both Windows 10 and Ubuntu 22.04. It would be nice not to have those errors pop up every time you open FutureSDR with VS Code.

    opened by jschiefer 7
  • Panic if audio device and requested configuration do not match

    Panic if audio device and requested configuration do not match

    This PR solves an issue I had with the AudioSink block. My audio device does not support 48 kHz sample rate. The AudioSink would simply block without an error message.

    My approach is to provide a different new function that will use the default settings of the default device.

    This PR is just a simple fix to make the examples work. Better error handling would probably also help.

    I am looking forward for any feedback.

    opened by phlorian 7
  • FIRFilter Implementation as well as Decimation and simple Quadrature Demodulation

    FIRFilter Implementation as well as Decimation and simple Quadrature Demodulation

    I have pushed here an early version (read as non-optimized) version of FIR filter along with simple Decimation and Quadrature Demodulation blocks. My intent was to generate the necessary code to begin processing the RDS data stream in the FM broadcasts. The submitted code did function to generate a clean signal with the following flow graph:

    let src = FileSourceBuilder::new(mem::size_of::<Complex<f32>>(), "test.dat".to_string()).build();
    let hd = HeadBuilder::new(mem::size_of::<Complex<f32>>(), 10000*4096).build();
    let decimation = DecimationBuilder::<Complex<f32>>::new()
        .sample_rate(2.56e6)
        .decimation(12)
        .build();
    let fir = FIRFilterBuilder::new()
        .fft_width(2048)
        .response_type(FIRFilterResponseShape::LowPass(100000_f32))
        .impulse_size(300)
        .sample_rate(2.56e6/12_f32)
        .build();
    let demod = QuadratureDemodulation::new();
    
    let src = fg.add_block(src);
    let hd = fg.add_block(hd);
    let decimation = fg.add_block(decimation);
    let fir = fg.add_block(fir);
    let vsnk = fg.add_block(vsnk);
    let demod = fg.add_block(demod);
    
    fg.connect_stream(src, "out", hd, "in")?;
    fg.connect_stream(hd, "out", decimation, "in")?;
    fg.connect_stream(decimation, "out", fir, "in")?;
    fg.connect_stream(fir, "out", demod, "in")?;
    fg.connect_stream(demod, "out", vsnk, "in")?;
    

    I am not suggesting that this code is ready for merge, but could be a good discussion starter. I realize that there has been a recent addition of the FIR filter. Maybe my attached code could help to make it more user friendly / flexible. :)

    opened by justacec 7
  • Instructions on how to start the frontend with FFT waterfall

    Instructions on how to start the frontend with FFT waterfall

    When I run cargo run --example soapy --features="soapy" it starts okay, but when I visit http://127.0.0.1:1337/ I get 404: Not Found. Are there more steps needed to start the frontend with the FFT waterfall? Running make in frontend subdirectory succeeds.

    opened by mryndzionek 7
  • Added basic application performing WBFM demodulation using liquid-dsp

    Added basic application performing WBFM demodulation using liquid-dsp

    An example performing WBFM demodulation. The example app has to blocks:

    Let me know if this approach (using liquid-dsp via bindgen) is acceptable. The example is fully functional - I can listen to FM radio stations using my RTLSDR. There are audio buffer underruns, but probably due to audio sink misconfiguration.

    opened by mryndzionek 7
  • Soapy: multiple channel configuration

    Soapy: multiple channel configuration

    I've made a first attempt at: https://github.com/etschneider/FutureSDR/tree/ets_new_soapy

    [EDIT: I pushed up some major changes and am adjusting this comment to match. I hope no one was looking at the original code.]

    If anyone interested, please review and comment. This isn't pull ready,I just want to see if this general approach is acceptable before spending more time on it.

    I made a new blocks::soapy sub-module, since the code is more complex. I'm using the examples/soapy_multichan.rs as a test case. (Perhaps some #[ignore] tests in the soapy module would be better? Or both?) [EDIT: I've added some integration tests]

    A few points:

    • The new 'cmd' port is used for all the new configuration methods, and supports the dict format of the GNU Radio Soapy block, among others.
    • The SoapyConfig type is meant to allow arbitrarily configurations of all channels/directions with a single message
    • There is also a new SoapyCommand enum, but it doesn't really add anything currently.
    • Since the configuration logic is the same for SoapySource and SoapySink, I've made a generic SoapyDevice<stream type> parent for them both. Trying to keep it DRY.
    • I tend to think that the old freq and sample_rate ports should be removed. This would be a breaking change, so???
    opened by etschneider 6
  • VCO and similar blocks

    VCO and similar blocks

    Voltage Controlled Oscillator (VCO) and other similar blocks are missing. I believe we can come with a common implementation for various use-cases. At least propose implementation for:

    • VCO taking as input the angle rate as in GNU Radio https://wiki.gnuradio.org/index.php/VCO_(complex)
    • CO taking as input the frequency

    It should also be a base for Phase Shift Keying (PSK, eg BPSK, GMSK, QPSK) and other constellations handling.

    Implementation experimentation started in my branch: https://github.com/loic-fejoz/FutureSDR/blob/feature/vco/src/blocks/signal_source/controlled_oscillator.rs

    opened by loic-fejoz 0
  • ADS-B decoder example

    ADS-B decoder example

    I implemented an ADS-B decoder with FutureSDR, and thought it could be nice to include as an example.

    It also contains a simple web-based map that uses the ctrl_port to interact with the flowgraph.

    It relies on adsb_deku for decoding the packets. While it supports a lot of formats, I have only implemented the most common ones, and the ones that were easiest to integrate.

    I have not performed any actual comparison to other ADS-B implementations, but it seems to perform quite well on my recordings and with an RTL-SDR with the stock telescopic antenna.

    Considering that many people are likely to use this example (along with the others) as an example of how to implement a decoder with FutureSDR, I think it should be as close as possible to "idiomatic" FutureSDR. So suggestions are very welcome. For instance, maybe it could make sense to merge some of the blocks, such as the preamble detector and demodulator.

    Also note that I copied the web server code from the zigbee example and only made some minor modifications. I am not familiar with gulp, so there might be some unnecessary stuff that can be removed.

    opened by AndersKaloer 1
  • Add rustfmt.toml and clippy.toml files

    Add rustfmt.toml and clippy.toml files

    It would be nice to have a standard for the project styles and clippy checks enforced by CI.

    E.g.: https://rust-lang.github.io/rustfmt/?version=v1.5.1&search=#imports_granularity

    opened by etschneider 2
  • CW blocks

    CW blocks

    Hi @bastibl ,

    i created some blocks to encode and decode Morse Code messages.

    You can try them with the following example program:

    use futuresdr::runtime::{Flowgraph, Runtime};
    use futuresdr::blocks::{ConsoleSink, SoapySinkBuilder, SoapySourceBuilder, VectorSource};
    use futuresdr::anyhow::{Result};
    use futuresdr::blocks::cw::{CharToCWBuilder,CWToCharBuilder, CWToIQBuilder, IQToCWBuilder};
    use futuresdr::runtime::buffer::slab::Slab;
    
    
    #[tokio::main]
    async fn main() -> Result<()> {
    
        let frequency = 1210e6;
        let sample_rate = 250e3;
        let tx_gain = 0.;
        let tx_dev_filter = "driver=bladerf"; //,xb200=auto
    
        /*let rx_gain = 49.6;
        let rx_dev_filter = "driver=rtlsdr";*/
    
        let mut fg = Flowgraph::new();
    
        let chars = vec!['S', 'O', 'S', ' ', 'S', 'O', 'S'];
    
        let vector_src = fg.add_block(VectorSource::new(chars));
        let char_to_cw = fg.add_block(CharToCWBuilder::new().build());
        let cw_to_iq = fg.add_block(CWToIQBuilder::new().dot_length(100.).sample_rate(250e3).smoothness(60.).build());
        let soapy_snk = fg.add_block(SoapySinkBuilder::new().freq(frequency).sample_rate(sample_rate).gain(tx_gain).filter(tx_dev_filter).build());
    
        /*let soapy_src = fg.add_block(SoapySourceBuilder::new().freq(frequency).sample_rate(sample_rate).gain(rx_gain).filter(rx_dev_filter).build());
        let iq_to_cw = fg.add_block(IQToCWBuilder::new().dot_length(100.).sample_rate(250e3).accuracy(70).build());
        let cw_to_char = fg.add_block(CWToCharBuilder::new().build());
        let console_snk = fg.add_block(ConsoleSink::<char>::new(""));*/
    
    
        fg.connect_stream(vector_src, "out", char_to_cw, "in")?;
        fg.connect_stream(char_to_cw, "out", cw_to_iq, "in")?;
        //fg.connect_stream(cw_to_iq, "out", soapy_snk, "in")?;
        fg.connect_stream_with_type(cw_to_iq, "out", soapy_snk, "in", Slab::with_size(4096))?;
    
        /*fg.connect_stream(soapy_src, "out", iq_to_cw, "in")?;
        fg.connect_stream(iq_to_cw, "out", cw_to_char, "in")?;
        fg.connect_stream(cw_to_char, "out", console_snk, "in")?;*/
    
        let rt = Runtime::new();
        rt.run(fg)?;
    
        Ok(())
    }
    

    Use the following Cargo.toml:

    [package]
    name = "morse_chat"
    version = "0.1.0"
    edition = "2021"
    
    # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    
    [dependencies]
    futuresdr = { git = "https://github.com/ratzrattillo/FutureSDR", branch = "cw", features = [ "soapy" ]}
    soapysdr = { version = "*" }
    tokio = { version = "*", features = ["full"] }
    

    If you would like to add it to the runtime i would be happy. Please feel free to change the code as needed.

    opened by ratzrattillo 5
  • runtime:   do not return error on terminate msg

    runtime: do not return error on terminate msg

    Also added an Err check in the executor loop of SmolScheduler::new() when testing. Probably should remain in some form.

    Left commented-out deadlock code in: tests/runtime::fg_terminate()

    refs: #80

    opened by etschneider 5
Owner
FutureSDR
An Async SDR Runtime for Heterogeneous Architectures
FutureSDR
📺 Netflix in Rust/ React-TS/ NextJS, Actix-Web, Async Apollo-GraphQl, Cassandra/ ScyllaDB, Async SQLx, Kafka, Redis, Tokio, Actix, Elasticsearch, Influxdb Iox, Tensorflow, AWS

Fullstack Movie Streaming Platform ?? Netflix in RUST/ NextJS, Actix-Web, Async Apollo-GraphQl, Cassandra/ ScyllaDB, Async SQLx, Spark, Kafka, Redis,

null 34 Apr 17, 2023
Rust async runtime based on io-uring.

Monoio A thread-per-core Rust runtime with io_uring. 中文说明 Design Goal As a runtime based on io_uring, Monoio is designed to be the most efficient and

Bytedance Inc. 2.4k Jan 6, 2023
🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, SQLite, and MSSQL.

SQLx ?? The Rust SQL Toolkit Install | Usage | Docs Built with ❤️ by The LaunchBadge team SQLx is an async, pure Rust† SQL crate featuring compile-tim

launchbadge 7.6k Dec 31, 2022
TDS 7.2+ (mssql / Microsoft SQL Server) async driver for rust

Tiberius A native Microsoft SQL Server (TDS) client for Rust. Supported SQL Server versions Version Support level Notes 2019 Tested on CI 2017 Tested

Prisma 189 Dec 25, 2022
Simple, async embedded Rust

Cntrlr - Simple, asynchronous embedded Cntrlr is an all-in-one embedded platform for writing simple asynchronous applications on top of common hobbyis

Branan Riley 11 Jun 3, 2021
An async executor based on the Win32 thread pool API

wae An async executor based on the Win32 thread pool API use futures::channel::oneshot; #[wae::main] async fn main() { let (tx, rx) = oneshot::ch

Raphaël Thériault 10 Dec 10, 2021
Async positioned I/O with io_uring.

uring-positioned-io Fully asynchronized positioned I/O with io_uring. Basic Usage let files = vec![File::open("test.txt").unwrap()]; let context = Uri

Alex Chi 30 Aug 24, 2022
🐚 An async & dynamic ORM for Rust

SeaORM ?? An async & dynamic ORM for Rust SeaORM SeaORM is a relational ORM to help you build web services in Rust with the familiarity of dynamic lan

SeaQL 3.5k Jan 6, 2023
Quick Pool: High Performance Rust Async Resource Pool

Quick Pool High Performance Rust Async Resource Pool Usage DBCP Database Backend Adapter Version PostgreSQL tokio-postgres qp-postgres Example use asy

Seungjae Park 13 Aug 23, 2022
Macros that allow for implicit await in your async code.

suspend fn Disclaimer: this was mostly made as a proof of concept for the proposal below. I haven't tested if there is a performance cost to this macr

null 6 Dec 22, 2021
Dataloader-rs - Rust implementation of Facebook's DataLoader using async-await.

Dataloader Rust implementation of Facebook's DataLoader using async-await. Documentation Features Batching load requests with caching Batching load re

cksac 229 Nov 27, 2022
Diesel async connection implementation

A async interface for diesel Diesel gets rid of the boilerplate for database interaction and eliminates runtime errors without sacrificing performance

Georg Semmler 293 Dec 26, 2022
rust_arango enables you to connect with ArangoDB server, access to database, execute AQL query, manage ArangoDB in an easy and intuitive way, both async and plain synchronous code with any HTTP ecosystem you love.

rust_arango enables you to connect with ArangoDB server, access to database, execute AQL query, manage ArangoDB in an easy and intuitive way, both async and plain synchronous code with any HTTP ecosystem you love.

Foretag 3 Mar 24, 2022
High-level async Cassandra client written in 100% Rust.

CDRS tokio CDRS is production-ready Apache Cassandra driver written in pure Rust. Focuses on providing high level of configurability to suit most use

Kamil Rojewski 73 Dec 26, 2022
lightweight, async and zero-copy KV Store

KipDB 介绍 网络异步交互、零拷贝的轻量级KV数据库 基于PingCAP课程talent-plan 课程地址:https://github.com/pingcap/talent-plan/tree/master/courses/rust 内置多种持久化内核 HashStore: 基于哈希 Sle

Kould 34 Dec 18, 2022
Automatically deleted async I/O temporary files in Rust

async-tempfile Provides the TempFile struct, an asynchronous wrapper based on tokio::fs for temporary files that will be automatically deleted when th

Markus Mayer 3 Jan 4, 2023
Async Lightweight HTTP client using system native library if possible. (Currently under heavy development)

Async Lightweight HTTP Client (aka ALHC) What if we need async but also lightweight http client without using such a large library like reqwest, isahc

SteveXMH 7 Dec 15, 2022
Go like sync.WaitGroup implementation in Rust. (sync/async)

WAG Go like sync.WaitGroup implementation in Rust. (sync/async) | Examples | Docs | Latest Note | wag = "0.3.0" How to use, use wag::WaitGroup; let w

Doha Lee 2 Dec 15, 2022
An async Rust client for SurrealDB's RPC endpoint

An async Rust client for SurrealDB's RPC endpoint This crate serves as a temporary yet complete implementation of an async Rust client to connect to a

Thibault H 12 Jan 21, 2023