Different semantics
use std::ffi::{CStr, c_char};
use std::time::{SystemTime, SystemTimeError, UNIX_EPOCH};
unsafe extern "C" {
/// Create a formatted time based on timestamp `t`.
fn ctime(t: *const libc::time_t) -> *const c_char;
}
fn now_formatted() -> Result<String, SystemTimeError> {
let now = SystemTime::now().duration_since(UNIX_EPOCH)?;
let seconds = now.as_secs() as i64;
// SAFETY: `seconds` is generated by the system clock and will not cause
// overflow
let ptr = unsafe { ctime(&seconds) };
// SAFETY: ctime returns a pointer to a preallocated (non-null) buffer
let ptr = unsafe { CStr::from_ptr(ptr) };
// SAFETY: ctime uses valid UTF-8
let fmt = ptr.to_str().unwrap();
Ok(fmt.trim_end().to_string())
}
fn main() {
let t = now_formatted();
println!("{t:?}");
}
Some constructs that other languages allow cannot be expressed in the Rust language.
The ctime function modifies an internal buffer shared between calls. This
cannot be represented as Rust’s lifetimes.
'staticdoes not apply, as the semantics are different'adoes not apply, as the buffer outlives each call