#string

no-std str-concat

Concatenate two adjacent string slices

1 unstable release

Uses old Rust 2015

0.2.0 Feb 6, 2020
0.1.4 Jun 20, 2018
0.1.2 Jun 20, 2018
0.1.1 Jun 20, 2018
0.1.0 Jun 20, 2018

#148 in No standard library

Download history 1045/week @ 2024-06-17 1097/week @ 2024-06-24 878/week @ 2024-07-01 1060/week @ 2024-07-08 1435/week @ 2024-07-15 1288/week @ 2024-07-22 1022/week @ 2024-07-29 893/week @ 2024-08-05 1086/week @ 2024-08-12 1112/week @ 2024-08-19 1135/week @ 2024-08-26 833/week @ 2024-09-02 1046/week @ 2024-09-09 1002/week @ 2024-09-16 1107/week @ 2024-09-23 1392/week @ 2024-09-30

4,619 downloads per month
Used in 10 crates (via sv-parser-parser)

MIT/Apache

19KB
151 lines

str-concat

Crates.io Docs.rs

Concatenate two adjacent string slices.

Examples

use str_concat::{concat, concat_unordered, Error};

fn main() {
    let s = "0123456789";
    // ordered, `a` before `b`
    unsafe {
        // SAFETY: the slices are from the same `&str`.
        assert_eq!(Ok("0123456"), concat(&s[..5], &s[5..7]));
        assert_eq!(Ok("0123456"), concat_unordered(&s[..5], &s[5..7]));
    }

    // unordered, `b` before `a`
    unsafe {
        // SAFETY: the slices are from the same `&str`.
        assert_eq!(Err(Error::NotAdjacent), concat(&s[5..7], &s[..5]));
        assert_eq!(Ok("0123456"), concat_unordered(&s[5..7], &s[..5]));
    }
}

Safety

It is generally not safe to concatenate two adjacent slices. This is explained in #8, bluss/odds#25, rust-lang/rust#66111, rust-lang/rust#62765, rust-lang/rfcs#2806 and tokio-rs/bytes#347. To sum it up, when rust calculates offset to borrow part of a referenced type such as a slice, it makes the assumption that those offsets stem from the same allocation. If two different allocations are adjacent to each other, the concat* functions in this crate would readily combine them, breaking internal assumptions of rustc and thus may result in UB. Therefore, all functions in this crate are marked as unsafe. The user must ensure that the slices to be concatenated stem from the same allocation (the same String, Vec<_>, …).

Another edge-case are zero-sized types (ZST). Multiple slices over different ZST may point to the same memory-region. That is because instances of ZSTs, including slices, can not be identified by their address even for different types. This is because a ZST does not occupy any space, it does not "alias" any memory. As such, there is no need to actually allocate any space during runtime when using a ZST (or a Vec or slice of it). Instead, a slice to ZSTs may point to the smallest non-zero address with the correct alignment (for example vec![()].as_ptr() as usize == 1). Technically it's sound to arbitrarily elongate a slice of ZST given it already contains at least one element. However, we decided that semantically it doesn't make sense to use this functionality. As we also don't have any way to tell that two ZST slices are adjacent, we decided to always return an error if two ZST slices are passed to be concatenated. For further reading surrounding this issue with ZST slices, see #5, rust-lang/unsafe-code-guidelines#93 and rust-lang/unsafe-code-guidelines#168.

License

Licensed under either of

at your option.

No runtime deps