Ely Office: six offline-first desktop apps in Rust and GPUI
ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git), ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
This commit is contained in:
817 files changed
+143101
No files matched your search
@@ -0,0 +1,68 @@
|
||||
//! The name documents sign new comments and changes with.
|
||||
|
||||
use std::io;
|
||||
|
||||
/// The author name from settings, else the account's.
|
||||
pub fn name() -> io::Result<String> {
|
||||
let set = crate::settings::Shared::load()?.author;
|
||||
if !set.is_empty() {
|
||||
return Ok(set);
|
||||
}
|
||||
account()
|
||||
}
|
||||
|
||||
/// The account's full name, else its login name.
|
||||
pub fn account() -> io::Result<String> {
|
||||
let full = full_name()?;
|
||||
if !full.trim().is_empty() {
|
||||
return Ok(full.trim().to_string());
|
||||
}
|
||||
let key = if cfg!(windows) { "USERNAME" } else { "USER" };
|
||||
log::info!("user: no full name; the login name signs");
|
||||
std::env::var(key).map_err(|error| io::Error::other(format!("no {key}: {error}")))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn full_name() -> io::Result<String> {
|
||||
Ok(objc2_foundation::NSFullUserName().to_string())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn full_name() -> io::Result<String> {
|
||||
// The first comma field of the passwd comment.
|
||||
let entry = unsafe { libc::getpwuid(libc::getuid()) };
|
||||
if entry.is_null() {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
let gecos = unsafe { (*entry).pw_gecos };
|
||||
if gecos.is_null() {
|
||||
return Ok(String::new());
|
||||
}
|
||||
let text = unsafe { std::ffi::CStr::from_ptr(gecos) }.to_string_lossy();
|
||||
Ok(text.split(',').next().unwrap_or_default().to_string())
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn full_name() -> io::Result<String> {
|
||||
use windows_sys::Win32::Security::Authentication::Identity::{GetUserNameExW, NameDisplay};
|
||||
let mut size = 0u32;
|
||||
unsafe { GetUserNameExW(NameDisplay, std::ptr::null_mut(), &mut size) };
|
||||
// Accounts outside a domain have no display name.
|
||||
if size == 0 {
|
||||
return Ok(String::new());
|
||||
}
|
||||
let mut buffer = vec![0u16; size as usize];
|
||||
if unsafe { GetUserNameExW(NameDisplay, buffer.as_mut_ptr(), &mut size) } == 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
Ok(String::from_utf16_lossy(&buffer[..size as usize]))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn the_account_has_a_name() {
|
||||
let name = super::name().expect("a name");
|
||||
assert!(!name.is_empty());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user