Skip to content

Concatenate two adjacent string slices

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

oberien/str-concat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

Concatenate two adjacent string slices

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Languages