Format Rust sources at 100 columns

This commit is contained in:
Samuel Onoja committed 2026-10-22 01:28:03 +01:00
1 parent 4661f595f8
commit 610478f8c7
336 files changed
+23497 -7892

No files matched your search

+54 -16
View File
@@ -32,7 +32,8 @@ impl Appearance {
.and_then(|path| std::fs::read_to_string(path).ok())
.and_then(|source| Document::parse(&source).ok());
let mut theme = ferese_theme_client::service::current().presented;
if let Some(path) = path.filter(|path| ferese_config::config_path().as_deref() != Some(*path))
if let Some(path) =
path.filter(|path| ferese_config::config_path().as_deref() != Some(*path))
&& let Some(document) = &doc
&& let Ok(mut connection) = ferese_ipc::Connection::connect()
{
@@ -49,7 +50,11 @@ impl Appearance {
Self::from_document(user, doc, &theme)
}
fn from_document(user: &str, doc: Option<Document>, theme: &ferese_config::theme::ResolvedTheme) -> Self {
fn from_document(
user: &str,
doc: Option<Document>,
theme: &ferese_config::theme::ResolvedTheme,
) -> Self {
let doc = doc.map(|doc| doc.with_theme(theme));
let string = |key: &str, fallback: &str| {
doc.as_ref()
@@ -80,7 +85,9 @@ impl Appearance {
let loaded = load_wallpaper(&wallpaper_path, if reduce_transparency { 0. } else { blur });
let wallpaper_loaded = loaded.is_ok();
let wallpaper = loaded.unwrap_or_else(|_| {
image::Handle::from_bytes(include_bytes!("../../../assets/wallpapers/ferese.png").as_slice())
image::Handle::from_bytes(
include_bytes!("../../../assets/wallpapers/ferese.png").as_slice(),
)
});
let boolean = |key, fallback| {
doc.as_ref()
@@ -134,7 +141,10 @@ impl Appearance {
if self.wallpaper_pending.as_ref() == Some(&desired) {
return None;
}
if self.wallpaper_loaded && path == self.wallpaper_path && reduce == self.reduce_transparency {
if self.wallpaper_loaded
&& path == self.wallpaper_path
&& reduce == self.reduce_transparency
{
if self.wallpaper_pending.take().is_some() {
self.wallpaper_revision = self.wallpaper_revision.wrapping_add(1);
}
@@ -149,7 +159,11 @@ impl Appearance {
))
}
pub fn finish_wallpaper(&mut self, revision: u64, result: Result<image::Handle, String>) -> Result<(), String> {
pub fn finish_wallpaper(
&mut self,
revision: u64,
result: Result<image::Handle, String>,
) -> Result<(), String> {
if revision != self.wallpaper_revision {
return Ok(());
}
@@ -165,7 +179,11 @@ impl Appearance {
}
pub fn clock_format(&self) -> &'static str {
if self.twelve_hour { "%I:%M %p" } else { "%H:%M" }
if self.twelve_hour {
"%I:%M %p"
} else {
"%H:%M"
}
}
pub fn theme(&self) -> cosmic::Theme {
@@ -188,7 +206,8 @@ impl Appearance {
}
fn account_picture(user: &str) -> Option<image::Handle> {
let mut candidates = vec![std::path::PathBuf::from("/var/lib/AccountsService/icons").join(user)];
let mut candidates =
vec![std::path::PathBuf::from("/var/lib/AccountsService/icons").join(user)];
if let Some(home) = std::env::var_os("HOME") {
candidates.push(std::path::PathBuf::from(home).join(".face"));
}
@@ -206,11 +225,13 @@ fn account_picture(user: &str) -> Option<image::Handle> {
side,
)
.to_image();
let mut pixels = ::image::imageops::resize(&square, 256, 256, ::image::imageops::FilterType::Lanczos3);
let mut pixels =
::image::imageops::resize(&square, 256, 256, ::image::imageops::FilterType::Lanczos3);
// Clip the decoded thumbnail, so the avatar stays circular even on
// renderers that do not support rounded image clipping.
for (x, y, pixel) in pixels.enumerate_pixels_mut() {
let distance = ((x as f32 + 0.5 - 128.).powi(2) + (y as f32 + 0.5 - 128.).powi(2)).sqrt();
let distance =
((x as f32 + 0.5 - 128.).powi(2) + (y as f32 + 0.5 - 128.).powi(2)).sqrt();
let coverage = (128. - distance).clamp(0., 1.);
pixel[3] = (pixel[3] as f32 * coverage).round() as u8;
}
@@ -235,7 +256,11 @@ fn decode_avatar(path: &std::path::Path) -> Result<::image::RgbaImage, String> {
.custom_flags(libc::O_NONBLOCK)
.open(path)
.map_err(|error| error.to_string())?;
if !file.metadata().map_err(|error| error.to_string())?.is_file() {
if !file
.metadata()
.map_err(|error| error.to_string())?
.is_file()
{
return Err("Avatar is not a regular file".into());
}
@@ -323,7 +348,10 @@ mod tests {
}
match load_wallpaper(file.path(), 2.).unwrap() {
image::Handle::Rgba {
width, height, pixels, ..
width,
height,
pixels,
..
} => {
assert_eq!((width, height), (640, 360));
assert_eq!(pixels.len(), 640 * 360 * 4);
@@ -378,7 +406,10 @@ mod tests {
assert!(appearance.request_wallpaper(&theme).is_none());
theme.tokens.background.lock_path = Some(initial.clone());
let (_, path, _) = appearance.request_wallpaper(&theme).unwrap();
assert_eq!(path, initial, "an explicit lock image overrides the desktop wallpaper");
assert_eq!(
path, initial,
"an explicit lock image overrides the desktop wallpaper"
);
}
#[test]
@@ -395,7 +426,11 @@ mod tests {
assert!(decode_avatar(file.path()).is_err());
file.as_file().set_len(8 * 1024 * 1024 + 1).unwrap();
assert!(decode_avatar(file.path()).unwrap_err().contains("file limit"));
assert!(
decode_avatar(file.path())
.unwrap_err()
.contains("file limit")
);
}
#[test]
@@ -429,9 +464,12 @@ mod tests {
)
.unwrap();
let document = Document::parse(&std::fs::read_to_string(&config).unwrap()).unwrap();
let theme = ferese_config::theme::resolve(&document, directory.path(), jiff::Timestamp::now(), |_| {
Err("unexpected file".into())
})
let theme = ferese_config::theme::resolve(
&document,
directory.path(),
jiff::Timestamp::now(),
|_| Err("unexpected file".into()),
)
.unwrap()
.theme;
let appearance = Appearance::from_document("no-such-test-user", Some(document), &theme);
+20 -7
View File
@@ -14,7 +14,8 @@ struct Response {
}
#[repr(C)]
struct Conversation {
callback: unsafe extern "C" fn(c_int, *mut *const Message, *mut *mut Response, *mut c_void) -> c_int,
callback:
unsafe extern "C" fn(c_int, *mut *const Message, *mut *mut Response, *mut c_void) -> c_int,
data: *mut c_void,
}
struct Credentials {
@@ -38,7 +39,8 @@ unsafe extern "C" fn converse(
unsafe {
*out = std::ptr::null_mut();
let credentials = &mut *(data as *mut Credentials);
let responses = libc::calloc(count as usize, std::mem::size_of::<Response>()) as *mut Response;
let responses =
libc::calloc(count as usize, std::mem::size_of::<Response>()) as *mut Response;
if responses.is_null() {
return CONV_ERR;
}
@@ -49,11 +51,13 @@ unsafe extern "C" fn converse(
} else {
match (*msg).style {
1 => {
credentials.password_prompts = credentials.password_prompts.saturating_add(1);
(credentials.password_prompts == 1).then_some(credentials.password.as_slice())
credentials.password_prompts =
credentials.password_prompts.saturating_add(1);
(credentials.password_prompts == 1)
.then_some(credentials.password.as_slice())
} // Never send the password as a second-factor response.
2 => Some(credentials.user.as_bytes_with_nul()), // PAM_PROMPT_ECHO_ON
3 | 4 => Some(&[][..]), // PAM_ERROR_MSG / PAM_TEXT_INFO
3 | 4 => Some(&[][..]), // PAM_ERROR_MSG / PAM_TEXT_INFO
_ => None,
}
};
@@ -61,7 +65,11 @@ unsafe extern "C" fn converse(
if !bytes.is_empty() {
let allocation = libc::malloc(bytes.len()) as *mut c_char;
if !allocation.is_null() {
std::ptr::copy_nonoverlapping(bytes.as_ptr(), allocation.cast(), bytes.len());
std::ptr::copy_nonoverlapping(
bytes.as_ptr(),
allocation.cast(),
bytes.len(),
);
(*responses.add(i)).text = allocation;
continue;
}
@@ -131,7 +139,12 @@ fn authenticate_with(user: &str, password: &str, config: Option<&CStr>) -> bool
let Ok(library) = libloading::Library::new("libpam.so.0") else {
return false;
};
type Start = unsafe extern "C" fn(*const c_char, *const c_char, *const Conversation, *mut *mut c_void) -> c_int;
type Start = unsafe extern "C" fn(
*const c_char,
*const c_char,
*const Conversation,
*mut *mut c_void,
) -> c_int;
type StartConf = unsafe extern "C" fn(
*const c_char,
*const c_char,
+92 -51
View File
@@ -22,7 +22,8 @@ fn main() -> iced::Result {
);
return Ok(());
}
let preview = args == ["--preview"] || (args.len() == 3 && args[0] == "--preview" && args[1] == "--config");
let preview = args == ["--preview"]
|| (args.len() == 3 && args[0] == "--preview" && args[1] == "--config");
let config = if preview && args.len() == 3 {
Some(std::path::PathBuf::from(&args[2]))
} else {
@@ -113,7 +114,8 @@ impl AuthState {
}
fn retry_ready(&mut self, now: Instant) -> bool {
if matches!(self, Self::Rejected(at) if now.saturating_duration_since(*at) >= Duration::from_secs(2)) {
if matches!(self, Self::Rejected(at) if now.saturating_duration_since(*at) >= Duration::from_secs(2))
{
*self = Self::Ready;
true
} else {
@@ -202,14 +204,17 @@ impl cosmic::Application for Locker {
if self.preview {
Subscription::none()
} else {
ferese_theme_client::service::subscription().map(|snapshot| Message::ThemeChanged(Box::new(snapshot)))
ferese_theme_client::service::subscription()
.map(|snapshot| Message::ThemeChanged(Box::new(snapshot)))
},
event::listen_with(|event, _, _| match event {
Event::PlatformSpecific(PlatformSpecific::Wayland(
wayland::Event::Output(..) | wayland::Event::SessionLock(..),
))
| Event::Window(window::Event::Opened { .. })
| Event::Keyboard(iced::keyboard::Event::ModifiersChanged(_)) => Some(Message::Event(Box::new(event))),
| Event::Keyboard(iced::keyboard::Event::ModifiersChanged(_)) => {
Some(Message::Event(Box::new(event)))
}
_ => None,
}),
if self.appearance.show_clock || self.appearance.show_date {
@@ -236,13 +241,18 @@ impl cosmic::Application for Locker {
self.appearance.accent = palette.accent;
self.appearance.on_accent = palette.on_accent;
self.appearance.radius = palette.radius;
self.appearance.font = ferese_theme::font(Some(&snapshot.presented.tokens.typography.font_family));
self.appearance.font =
ferese_theme::font(Some(&snapshot.presented.tokens.typography.font_family));
let theme = cosmic::command::set_theme(self.appearance.theme());
if let Some((revision, path, blur)) = self.appearance.request_wallpaper(&snapshot.theme) {
if let Some((revision, path, blur)) =
self.appearance.request_wallpaper(&snapshot.theme)
{
let wallpaper = cosmic::task::future(async move {
let result = tokio::task::spawn_blocking(move || appearance::load_wallpaper(&path, blur))
.await
.unwrap_or_else(|e| Err(e.to_string()));
let result = tokio::task::spawn_blocking(move || {
appearance::load_wallpaper(&path, blur)
})
.await
.unwrap_or_else(|e| Err(e.to_string()));
Message::WallpaperLoaded(revision, result)
});
return Task::batch([theme, wallpaper]);
@@ -284,7 +294,10 @@ impl cosmic::Application for Locker {
return focus();
}
if !self.confirmation.confirmed() || !self.state.may_submit() || self.password.is_empty() {
if !self.confirmation.confirmed()
|| !self.state.may_submit()
|| self.password.is_empty()
{
return Task::none();
}
@@ -337,9 +350,10 @@ impl Locker {
Event::Keyboard(iced::keyboard::Event::ModifiersChanged(modifiers)) => {
self.caps_lock = modifiers.contains(iced::keyboard::Modifiers::CAPS_LOCK);
}
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::Output(event, output)))
if !self.preview =>
{
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::Output(
event,
output,
))) if !self.preview => {
if matches!(event, wayland::OutputEvent::Removed) {
if let Some(id) = self.outputs.remove(&output) {
return session_lock::destroy_lock_surface(id);
@@ -352,33 +366,33 @@ impl Locker {
}
}
}
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::SessionLock(event))) if !self.preview => {
match event {
wayland::SessionLockEvent::Locked if self.confirmation.observe(&event) => {
use std::io::Write;
if std::env::var_os("FERESE_LOCK_READY").is_some() {
let _ = writeln!(std::io::stdout().lock(), "FERESE_LOCKED");
}
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::SessionLock(
event,
))) if !self.preview => match event {
wayland::SessionLockEvent::Locked if self.confirmation.observe(&event) => {
use std::io::Write;
if std::env::var_os("FERESE_LOCK_READY").is_some() {
let _ = writeln!(std::io::stdout().lock(), "FERESE_LOCKED");
}
wayland::SessionLockEvent::Requested if !self.started => {
self.started = true;
return Task::batch(
self.outputs
.iter()
.map(|(output, id)| session_lock::get_lock_surface(*id, output.clone())),
);
}
wayland::SessionLockEvent::Focused(..) => return focus(),
wayland::SessionLockEvent::Unlocked if self.state == AuthState::Unlocking => {
return iced::exit();
}
wayland::SessionLockEvent::Finished | wayland::SessionLockEvent::NotSupported => {
eprintln!("ferese-lock: compositor refused the lock");
return iced::exit();
}
_ => {}
}
}
wayland::SessionLockEvent::Requested if !self.started => {
self.started = true;
return Task::batch(
self.outputs.iter().map(|(output, id)| {
session_lock::get_lock_surface(*id, output.clone())
}),
);
}
wayland::SessionLockEvent::Focused(..) => return focus(),
wayland::SessionLockEvent::Unlocked if self.state == AuthState::Unlocking => {
return iced::exit();
}
wayland::SessionLockEvent::Finished | wayland::SessionLockEvent::NotSupported => {
eprintln!("ferese-lock: compositor refused the lock");
return iced::exit();
}
_ => {}
},
Event::Window(window::Event::Opened { .. }) => {
return focus();
}
@@ -403,7 +417,14 @@ impl Locker {
fn screen_content(&self, size: iced::Size) -> Element<'_, Message> {
let avatar_size = (size.height * 0.08).clamp(56., 88.);
let clock_size = (size.height * 0.06)
.min(size.width * if self.appearance.twelve_hour { 0.055 } else { 0.085 })
.min(
size.width
* if self.appearance.twelve_hour {
0.055
} else {
0.085
},
)
.clamp(32., 72.) as u16;
let margin = if size.width < 640. { 24. } else { 36. };
let top = (size.height * 0.09).max(24.);
@@ -412,7 +433,9 @@ impl Locker {
.password()
.padding([4, 10])
.size(14)
.style(ferese_theme::controls::lock_input(a.radius, a.accent, a.panel))
.style(ferese_theme::controls::lock_input(
a.radius, a.accent, a.panel,
))
.font(a.font)
.id(widget::Id::new("password"));
@@ -468,8 +491,15 @@ impl Locker {
self.label(&self.user, 16).class(iced::Color::WHITE),
widget::Space::new().height(6),
input,
self.label(if self.caps_lock { "Caps Lock is on" } else { self.status }, 12)
.class(iced::Color::WHITE.scale_alpha(0.68)),
self.label(
if self.caps_lock {
"Caps Lock is on"
} else {
self.status
},
12
)
.class(iced::Color::WHITE.scale_alpha(0.68)),
]
.spacing(12)
.align_x(iced::Alignment::Center)
@@ -492,10 +522,17 @@ impl Locker {
}
if a.show_date {
clock = clock.push(self.label(&self.date, 18).class(iced::Color::WHITE.scale_alpha(0.72)));
clock = clock.push(
self.label(&self.date, 18)
.class(iced::Color::WHITE.scale_alpha(0.72)),
);
}
let clock_height = if a.show_clock { clock_size as f32 * 1.3 } else { 0. } + if a.show_date { 24. } else { 0. };
let clock_height = if a.show_clock {
clock_size as f32 * 1.3
} else {
0.
} + if a.show_date { 24. } else { 0. };
let gap = (size.height * 0.44 - top - clock_height).max(24.);
let foreground = container(
column![
@@ -529,12 +566,14 @@ impl Locker {
})
.width(Length::Fill)
.height(Length::Fill)
.class(theme::Container::custom(move |_| widget::container::Style {
text_color: Some(iced::Color::WHITE.scale_alpha(0.65)),
background: Some(iced::Background::Color(iced::Color::from_rgba(
0.025, 0.035, 0.06, a.dim,
))),
..Default::default()
.class(theme::Container::custom(move |_| {
widget::container::Style {
text_color: Some(iced::Color::WHITE.scale_alpha(0.65)),
background: Some(iced::Background::Color(iced::Color::from_rgba(
0.025, 0.035, 0.06, a.dim,
))),
..Default::default()
}
}));
let background: Element<'_, Message> = image(a.wallpaper.clone())
.width(Length::Fill)
@@ -588,6 +627,8 @@ mod tests {
}
#[test]
fn password_messages_are_redacted() {
assert!(!format!("{:?}", Message::Input(Zeroizing::new("secret".into()))).contains("secret"));
assert!(
!format!("{:?}", Message::Input(Zeroizing::new("secret".into()))).contains("secret")
);
}
}
+25 -7
View File
@@ -18,8 +18,10 @@ impl Dispatch<wl_registry::WlRegistry, GlobalListContents> for Registry {
}
}
pub fn check_protocol() -> Result<(), String> {
let connection = Connection::connect_to_env().map_err(|e| format!("Wayland connection: {e}"))?;
let (globals, _) = registry_queue_init::<Registry>(&connection).map_err(|e| format!("Wayland registry: {e}"))?;
let connection =
Connection::connect_to_env().map_err(|e| format!("Wayland connection: {e}"))?;
let (globals, _) = registry_queue_init::<Registry>(&connection)
.map_err(|e| format!("Wayland registry: {e}"))?;
if globals
.contents()
.clone_list()
@@ -70,7 +72,11 @@ pub struct Confirmation {
}
impl Confirmation {
pub fn observe(&mut self, event: &cosmic::iced::event::wayland::SessionLockEvent) -> bool {
if !matches!(event, cosmic::iced::event::wayland::SessionLockEvent::Locked) || self.confirmed {
if !matches!(
event,
cosmic::iced::event::wayland::SessionLockEvent::Locked
) || self.confirmed
{
return false;
}
self.confirmed = true;
@@ -88,7 +94,12 @@ mod tests {
fn invalid_confirmation_returns_without_waiting_for_or_killing_the_locker() {
for message in ["unexpected", "FERESE_LOCKED"] {
let mut child = Command::new("sh")
.args(["-c", "printf '%s\\n' \"$1\"; exec sleep 3", "lock-fixture", message])
.args([
"-c",
"printf '%s\\n' \"$1\"; exec sleep 3",
"lock-fixture",
message,
])
.stdout(Stdio::piped())
.spawn()
.unwrap();
@@ -105,7 +116,9 @@ mod tests {
#[test]
fn only_compositor_confirmation_marks_the_lock_ready_once() {
use cosmic::iced::event::wayland::SessionLockEvent::{Finished, Locked, NotSupported, Requested};
use cosmic::iced::event::wayland::SessionLockEvent::{
Finished, Locked, NotSupported, Requested,
};
let mut c = Confirmation::default();
for event in [Requested, Requested, Finished, NotSupported] {
assert!(!c.observe(&event));
@@ -131,7 +144,9 @@ pub fn minute_ticks() -> impl cosmic::iced::futures::Stream<Item = ()> {
})
}
pub fn retry_deadline(at: &std::time::Instant) -> impl cosmic::iced::futures::Stream<Item = ()> + use<> {
pub fn retry_deadline(
at: &std::time::Instant,
) -> impl cosmic::iced::futures::Stream<Item = ()> + use<> {
let at = *at;
cosmic::iced::futures::stream::once(async move {
tokio::time::sleep(Duration::from_secs(2).saturating_sub(at.elapsed())).await;
@@ -149,6 +164,9 @@ mod clock_tests {
until_next_minute(Duration::from_millis(119_999)),
Duration::from_millis(1)
);
assert_eq!(until_next_minute(Duration::from_secs(125)), Duration::from_secs(55));
assert_eq!(
until_next_minute(Duration::from_secs(125)),
Duration::from_secs(55)
);
}
}