UnixString is An FFI-friendly null-terminated byte string

Overview

unixstring codecov Crates.io Docs

UnixString is an FFI-friendly null-terminated byte string that may be constructed from a String, a CString, a PathBuf, an OsString or a collection of bytes.

An UnixString can then be converted into a slice of CStr, Path or OsStr in infallible and zero-cost operations.

Why?

UnixString aims to be useful in any scenario where you'd like to use FFI (specially with C) on Unix systems. If you have a PathBuf, for example, you can send that data to a libc function, such as stat, but you'd have to first allocate a CString (or something analogous) to do so.

The same is true with OsString and String because these three types are allowed to have internal zero bytes and are not null-terminated.

A UnixString is very close to what a CString is but with increased flexibility and usability. A CString cannot be changed or increased after instantited, while UnixString is growable through its push and push_bytes methods, somewhat similar to OsString.

A CString also does not have direct reference conversions to anything but &[u8] or &CStr, while UnixString has those and more (described below).

Obtaining references from an UnixString

Into Function Notes
&CStr UnixString::as_c_str Available through AsRef as well
&Path UnixString::as_path Available through AsRef as well
&str UnixString::as_str Fails if the bytes of the UnixString aren't valid UTF-8
&[u8] UnixString::as_bytes Returns the bytes of the UnixString without the null terminator
&[u8] UnixString::as_bytes_with_nul Returns the bytes of the UnixString with the null terminator
&OsStr UnixString::as_os_str Available through AsRef as well
* const c_char UnixString::as_ptr

Creating an UnixString

From Potential failure Trait impl Function
CString Infallible From UnixString::from_cstring
PathBuf Fails if contains an interior zero byte TryFrom UnixString::from_pathbuf
String Fails if contains an interior zero byte TryFrom UnixString::from_string
Vec Fails if contains an interior zero byte TryFrom UnixString::from_bytes
OsString Fails if contains an interior zero byte TryFrom UnixString::from_os_string
* const c_char Unsafe, see the docs for more info None UnixString::from_ptr

Converting from an UnixString

Into Function Notes
CString UnixString::into_cstring
PathBuf UnixString::into_pathbuf
OsString UnixString::into_os_string
String UnixString::into_string Fails if the UnixString's bytes are not valid UTF-8
String UnixString::into_string_lossy
String UnixString::to_string_lossy Non-moving version of UnixString::into_string_lossy
String UnixString::into_string_unchecked Unsafe: creates a String without checking if the bytes are valid UTF-8
Vec UnixString::into_bytes Returns the bytes of the UnixString without the null terminator
Vec UnixString::into_bytes_with_nul Returns the bytes of the UnixString with the null terminator

All of the above are also available through .into().

Examples

Creating an UnixString with bytes received through FFI

use libc::{c_char, getcwd};
use unixstring::UnixString;

fn main() {
    const PATH_SIZ: usize = 1024;
    let mut buf: [c_char; 1024] = [0; 1024];

    let ptr = &mut buf as *mut c_char;

    unsafe { getcwd(ptr, PATH_SIZ) };

    if ptr.is_null() {
        panic!("getcwd failed");
    }

    let unix_string = unsafe { UnixString::from_ptr(ptr as *const c_char) };

    assert_eq!(unix_string.as_path(), std::env::current_dir().unwrap())
}

Using an UnixString to send bytes through FFI

use std::{convert::TryFrom, env};

use unixstring::UnixString;

fn stat(path: &UnixString) -> std::io::Result
    {
    
   // Safety: The all-zero byte-pattern is a valid `struct stat`
    
   let 
   mut stat_buf 
   = 
   unsafe { std
   ::mem
   ::
   zeroed() };

    
   if 
   -
   1 
   == 
   unsafe { libc
   ::
   lstat(path.
   as_ptr(), 
   &
   mut stat_buf) } {
        
   let io_err 
   = std
   ::io
   ::Error
   ::
   last_os_error();
        
   Err(io_err)
    } 
   else {
        
   Ok(stat_buf)
    }
}



   fn 
   main() -> std::io::
   Result<()>{
    
   for arg 
   in env
   ::
   args_os().
   map(UnixString
   ::try_from).
   flatten() {
        
   let stat 
   = 
   stat(
   &arg)?;
        
        
   let size 
   = stat.st_size;

        
   println!(
   "{} occupies {} bytes.", arg.
   as_path().
   display(), size);
    }

    
   Ok(())
}
  
Issues
  • Add GitHub Actions workflow

    Add GitHub Actions workflow

    null

    hacktoberfest-accepted 
    opened by vrmiguel 0
  • CI: add Tarpaulin for code coverage reports

    CI: add Tarpaulin for code coverage reports

    null

    hacktoberfest-accepted 
    opened by vrmiguel 0
  • Dev

    Dev

    null

    opened by vrmiguel 0
  • Bump version, document `as_mut_ptr` and add `set_len`

    Bump version, document `as_mut_ptr` and add `set_len`

    null

    hacktoberfest-accepted 
    opened by vrmiguel 0
  • Add Windows support

    Add Windows support

    null

    opened by vrmiguel 0
  • Create std::fs::File from UnixString without allocating

    Create std::fs::File from UnixString without allocating

    When opening a std::fs::File in Rust on Linux right now, you give it an AsRef<Path>, which is turned into a CString, reallocating the string in the process (rust/library/std/src/sys/unix/fs.rs, function cstr()). There is no way to use safe rust and just the standard library to open a File without allocating a String on the heap. Even using this library to convert a UnixString into a Path to open a File, the standard library has no knowledge that the UnixString was nul terminated, so must reallocate.

    It would be nice if this library (or one based on it) gave that capability. A File::open<P:AsRef<UnixStr>> that is guaranteed to not allocate in the success case; the error case might allocate an String to describe the error.

    Also you may have noticed I included a signature with UnixStr. I think it makes sense to have separate UnixString and UnixStr (owned vs borrowed) just like the standard library has for String vs str, CString vs CStr, OsString vs OsStr, etc.

    opened by maxbla 0
Owner
Vinícius Miguel
barely passed the Turing test
Vinícius Miguel
BearLibTerminal FFI for Rust

BearLibTerminal.rs BearLibTerminal FFI for Rust. Requirements You need to compile/get a precompiled version of BearLibTerminal yourself and put it som

наб 28 Sep 13, 2021
This is choose, a human-friendly and fast alternative to cut and (sometimes) awk

Choose This is choose, a human-friendly and fast alternative to cut and (sometimes) awk Features terse field selection syntax similar to Python's list

Ryan Geary 933 Nov 27, 2021
fd is a program to find entries in your filesystem. It is a simple, fast and user-friendly alternative to find

fd is a program to find entries in your filesystem. It is a simple, fast and user-friendly alternative to find. While it does not aim to support all of find's powerful functionality, it provides sensible (opinionated) defaults for a majority of use cases.

David Peter 19.6k Nov 24, 2021
A user-friendly TUI client for Matrix written in Rust!

Konoha A user-friendly TUI client for Matrix written in Rust! Notice: The client is currently not usable and is only hosted on GitHub for version cont

L3af 11 Nov 8, 2021
Grep with human-friendly search output

hgrep: Human-friendly GREP hgrep is a grep tool to search files with given pattern and print the matched code snippets with human-friendly syntax high

Linda_pp 274 Nov 30, 2021
LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.

LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values. Authors: Sanjay Ghem

Google 27.1k Nov 24, 2021
Read input lines as byte slices for high efficiency

bytelines This library provides an easy way to read in input lines as byte slices for high efficiency. It's basically lines from the standard library,

Isaac Whitfield 43 Nov 19, 2021
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 106 Nov 27, 2021
Parse byte size into integer accurately.

parse-size parse-size is an accurate, customizable, allocation-free library for parsing byte size into integer. use parse_size::parse_size; assert_eq

null 18 Nov 28, 2021
Library + CLI-Tool to measure the TTFB (time to first byte) of HTTP requests. Additionally, this crate measures the times of DNS lookup, TCP connect and TLS handshake.

TTFB: CLI + Lib to Measure the TTFB of HTTP/1.1 Requests Similar to the network tab in Google Chrome or Mozilla Firefox, this crate helps you find the

Philipp Schuster 16 Nov 13, 2021
decode a byte stream of varint length-encoded messages into a stream of chunks

length-prefixed-stream decode a byte stream of varint length-encoded messages into a stream of chunks This crate is similar to and compatible with the

James Halliday 3 Sep 9, 2021
Finds matching solidity function signatures for a given 4 byte signature hash and arguments.

Finds matching solidity function signatures for a given 4 byte signature hash and arguments. Useful for finding collisions or 0x00000000 gas saving methods (though there are better techniques for saving gas on calldata)

null 10 Nov 21, 2021
Automatically generates Rust FFI bindings to C (and some C++) libraries.

bindgen bindgen automatically generates Rust FFI bindings to C (and some C++) libraries. For example, given the C header doggo.h: typedef struct Doggo

The Rust Programming Language 2.4k Nov 28, 2021
Rust in Haskell FFI Example

Provides an example for using Rust in Haskell. To use this you'll need cargo, rustc, cabal and GHC installed. To execute the example run the following

Michael Gattozzi 20 Oct 27, 2020
BearLibTerminal FFI for Rust

BearLibTerminal.rs BearLibTerminal FFI for Rust. Requirements You need to compile/get a precompiled version of BearLibTerminal yourself and put it som

наб 28 Sep 13, 2021
High level FFI binding around the sys mount & umount2 calls, for Rust

sys-mount High level FFI bindings to the mount and umount2 system calls, for Rust. Examples Mount This is how the mount command could be written with

Pop!_OS 21 Nov 8, 2021
libc - Raw FFI bindings to platforms' system libraries

libc provides all of the definitions necessary to easily interoperate with C code (or "C-like" code) on each of the platforms that Rust supports. This includes type definitions (e.g. c_int), constants (e.g. EINVAL) as well as function headers (e.g. malloc).

The Rust Programming Language 1.2k Nov 22, 2021
A safe Rust FFI binding for the NVIDIA® Tools Extension SDK (NVTX).

NVIDIA® Tools Extension SDK (NVTX) is a C-based Application Programming Interface (API) for annotating events, code ranges, and resources in your applications. Official documentation for NVIDIA®'s NVTX can be found here.

Spencer Imbleau 26 Nov 11, 2021
A cross-platform crate with FFI bindings to allow for complex vehicle ECU diagnostics.

ecu_diagnostics A cross-platform crate with FFI bindings to allow for complex vehicle ECU diagnostics. IMPORTANT Currently this crate is not 100% read

Ashcon Mohseninia 25 Nov 17, 2021
Membrane is an opinionated crate that generates a Dart package from a Rust library. Extremely fast performance with strict typing and zero copy returns over the FFI boundary via bincode.

Membrane is an opinionated crate that generates a Dart package from a Rust library. Extremely fast performance with strict typing and zero copy returns over the FFI boundary via bincode.

Jerel Unruh 8 Nov 17, 2021
Simplified glue code generation for Deno FFI libraries written in Rust.

deno_bindgen This tool aims to simplify glue code generation for Deno FFI libraries written in Rust. Quickstart # install CLI deno install -Afq -n den

Divy Srivastava 39 Nov 18, 2021
Core Rust-C FFI for Stackmate Wallet.

STACKMATE-CORE A Rust-C FFI library exposing composite functionality from rust-bitcoin & bdk; to create cross-platform descriptor wallets. Currently u

Vishal Menon 2 Nov 29, 2021
Experimental Rust tool for generating FFI definitions allowing many other languages to call Rust code

Diplomat is an experimental Rust tool for generating FFI definitions allowing many other languages to call Rust code. With Diplomat, you can simply define Rust APIs to be exposed over FFI and get high-level C, C++, and JavaScript bindings automatically!

null 35 Nov 19, 2021
A user-friendly database interface

Diwata Diwata is a database interface for PostgreSQL,Mysql, Sqlite with the goal of being usable, user-friendly with its basic and advanced functional

Jovansonlee Cesar 390 Nov 12, 2021
A simple, fast and user-friendly alternative to 'find'

fd [中文] [한국어] fd is a program to find entries in your filesytem. It is a simple, fast and user-friendly alternative to find. While it does not aim to

David Peter 19.6k Nov 23, 2021
Rust friendly bindings to *nix APIs

Rust bindings to *nix APIs Documentation (Releases) Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin, ...). The goa

null 1.6k Nov 22, 2021
Linear Programming for Rust, with an user-friendly API. This crate allows modeling LP problems, and let's you solve them with various solvers.

good_lp A Linear Programming modeler that is easy to use, performant with large problems, and well-typed. use good_lp::{variables, variable, coin_cbc,

Rust Operations Research 58 Nov 15, 2021
Valheim Docker powered by Odin. The Valheim dedicated gameserver manager which is designed with resiliency in mind by providing automatic updates, world backup support, and a user friendly cli interface.

Valheim Docker If you are looking for a guide on how to get started click here Mod Support! It is supported to launch the server with BepInEx but!!!!!

Michael 603 Nov 25, 2021
A tilemap rendering crate for bevy which is more ECS friendly.

bevy_ecs_tilemap A tilemap rendering plugin for bevy which is more ECS friendly by having an entity per tile. Features A tile per entity Fast renderin

John 118 Nov 25, 2021