jcmoyer / rust-lua53

Lua 5.3 bindings for Rust
MIT License
158 stars 45 forks source link

Provide `to_bytes` method. #47

Closed Parakleta closed 7 years ago

Parakleta commented 8 years ago

Lua strings are not always string and are in fact byte arrays instead (they can contain embedded '\0' and do not need to be UTF8 compliant). I am using them to pass around CBOR encoded data.

I propose creating a to_bytes and check_bytes function to replace to_str_in_place and check_string respectively. A to_str and check_str function can then be simply made by calling the *_bytes versions and doing the conversion as a convenience.

  pub fn to_str(&mut self, index: Index) -> Option<&str> {
    self.to_bytes(index).and_then(|b| { str::from_utf8(b).ok() })
  }

  pub fn check_str(&mut self, index: Index) -> &str {
    str::from_utf8(self.check_bytes(index)).unwrap()
  }

The current to_str function should probably be renamed to something like to_display since it calls luaL_tolstring which goes through the __tostring metamethod and failing that constructs a display/debug name of typename: 0x0ptraddr and is more closely aligned with the Display or Debug traits in Rust.

  pub fn to_display(&mut self, index: Index) -> Result<&str,Option<&[u8]>> {
    let mut len = 0;
    let ptr = unsafe { ffi::luaL_tolstring(self.L, index, &mut len) };
    if ptr.is_null() {
      Err(None)
    } else {
      let slice = unsafe { slice::from_raw_parts(ptr as *const u8, len as usize) };
      str::from_utf8(slice).or(Err(Some(slice)))
    }
  }
jugglerchris commented 7 years ago

Similarly, I need to pass non-UTF8 data to Lua. I'm not bothered about the name, but I agree there's a need for handling arbitrary &[u8]/Vec<u8> in both directions as well as UTF-8 strings.