Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use ::std::{*,
- borrow::Cow,
- convert::Infallible,
- ffi::{
- CStr,
- CString,
- },
- };
- #[derive(Debug)]
- pub
- struct InnerNullError {
- pub null_position: usize,
- }
- impl error::Error for InnerNullError {}
- impl fmt::Display for InnerNullError {
- fn fmt (
- self: &'_ Self,
- stream: &'_ mut fmt::Formatter<'_>,
- ) -> fmt::Result
- {
- write!(stream, concat!(
- "Conversion to C string failed: ",
- "inner null byte at position {}.",
- ), self.null_position)
- }
- }
- pub trait Str<'a> {
- type Err : error::Error;
- fn try_into_cstr (
- self: Self
- ) -> Result<Cow<'a, CStr>, Self::Err>;
- }
- impl<'a> Str<'a> for &'a CStr {
- type Err = Infallible;
- fn try_into_cstr (
- self: Self
- ) -> Result<Cow<'a, CStr>, Self::Err>
- {
- Ok(self.into())
- }
- }
- impl<'a> Str<'a> for String {
- type Err = InnerNullError;
- fn try_into_cstr (
- self: Self
- ) -> Result<Cow<'a, CStr>, Self::Err>
- {
- match CString::new(self) {
- | Ok(c_string) => Ok(c_string.into()),
- | Err(nul_error) => Err(InnerNullError {
- null_position: nul_error.nul_position(),
- }),
- }
- }
- }
- impl<'a> Str<'a> for &'a str {
- type Err = InnerNullError;
- fn try_into_cstr (
- self: Self
- ) -> Result<Cow<'a, CStr>, Self::Err>
- {
- match self.as_bytes().iter().position(|x| *x == b'\0') {
- | None => unsafe {
- Ok(CString::from_vec_unchecked(
- self.bytes()
- .chain(iter::once(b'\0'))
- .collect()
- ).into())
- },
- | Some(null_position)
- if null_position == self.len() - 1
- => unsafe {
- Ok(CStr::from_bytes_with_nul_unchecked(
- self.as_bytes()
- ).into())
- },
- | Some(null_position) => {
- Err(InnerNullError {
- null_position,
- })
- },
- }
- }
- }
- fn puts<'__> (s: impl Str<'__>)
- {
- let c_str =
- s .try_into_cstr()
- .unwrap_or_else(|err| panic!("{}", err))
- ;
- unsafe {
- ::libc::puts(c_str.as_ptr());
- }
- }
- fn main ()
- {
- puts("Hello, World!");
- puts("Hello, World!".to_string());
- puts(CStr::from_bytes_with_nul(b"Hello, World!\0").unwrap());
- puts("Hell\0, World!");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement