Format Rust sources at 100 columns
This commit is contained in:
1 parent
4661f595f8
commit
610478f8c7
336 files changed
+23497
-7892
No files matched your search
@@ -28,7 +28,12 @@ pub struct Id {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
#[serde(tag = "kind", content = "value", rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[serde(
|
||||
tag = "kind",
|
||||
content = "value",
|
||||
rename_all = "kebab-case",
|
||||
deny_unknown_fields
|
||||
)]
|
||||
pub enum Value {
|
||||
Indeterminate,
|
||||
Progress(f32),
|
||||
@@ -51,7 +56,12 @@ impl Value {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
#[serde(tag = "kind", content = "data", rename_all = "kebab-case", deny_unknown_fields)]
|
||||
#[serde(
|
||||
tag = "kind",
|
||||
content = "data",
|
||||
rename_all = "kebab-case",
|
||||
deny_unknown_fields
|
||||
)]
|
||||
pub enum Template {
|
||||
Progress,
|
||||
Timer,
|
||||
@@ -96,20 +106,39 @@ pub struct Data {
|
||||
impl Data {
|
||||
pub fn validate(&mut self, now: Time) -> Result<(), &'static str> {
|
||||
text(&self.title)?;
|
||||
if self.output.as_ref().is_some_and(|output| text(output).is_err()) {
|
||||
if self
|
||||
.output
|
||||
.as_ref()
|
||||
.is_some_and(|output| text(output).is_err())
|
||||
{
|
||||
return Err("invalid output name");
|
||||
}
|
||||
if self.icon.len() > 64 || !self.icon.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-') {
|
||||
if self.icon.len() > 64
|
||||
|| !self
|
||||
.icon
|
||||
.bytes()
|
||||
.all(|b| b.is_ascii_alphanumeric() || b == b'-')
|
||||
{
|
||||
return Err("icon must be a symbolic name");
|
||||
}
|
||||
if !matches!(
|
||||
self.icon.as_str(),
|
||||
"hammer" | "timer" | "download" | "media" | "microphone" | "camera" | "call" | "notification" | "ferese"
|
||||
"hammer"
|
||||
| "timer"
|
||||
| "download"
|
||||
| "media"
|
||||
| "microphone"
|
||||
| "camera"
|
||||
| "call"
|
||||
| "notification"
|
||||
| "ferese"
|
||||
) {
|
||||
self.icon = "ferese".into();
|
||||
}
|
||||
match &mut self.value {
|
||||
Value::Progress(progress) if !progress.is_finite() || !(0.0..=1.0).contains(progress) => {
|
||||
Value::Progress(progress)
|
||||
if !progress.is_finite() || !(0.0..=1.0).contains(progress) =>
|
||||
{
|
||||
return Err("progress must be finite and between zero and one");
|
||||
}
|
||||
Value::Text(value) => text(value)?,
|
||||
@@ -128,15 +157,28 @@ impl Data {
|
||||
_ => {}
|
||||
}
|
||||
match &self.template {
|
||||
Template::Timer if !matches!(self.value, Value::Countdown { .. } | Value::PausedCountdown { .. }) => {
|
||||
Template::Timer
|
||||
if !matches!(
|
||||
self.value,
|
||||
Value::Countdown { .. } | Value::PausedCountdown { .. }
|
||||
) =>
|
||||
{
|
||||
return Err("timer requires a countdown");
|
||||
}
|
||||
Template::Progress if matches!(self.value, Value::Countdown { .. } | Value::PausedCountdown { .. }) => {
|
||||
Template::Progress
|
||||
if matches!(
|
||||
self.value,
|
||||
Value::Countdown { .. } | Value::PausedCountdown { .. }
|
||||
) =>
|
||||
{
|
||||
return Err("countdown requires timer template");
|
||||
}
|
||||
Template::Media { artist, .. } => {
|
||||
text(artist)?;
|
||||
if !matches!(self.value, Value::Text(_) | Value::Indeterminate | Value::Progress(_)) {
|
||||
if !matches!(
|
||||
self.value,
|
||||
Value::Text(_) | Value::Indeterminate | Value::Progress(_)
|
||||
) {
|
||||
return Err("invalid media value");
|
||||
}
|
||||
}
|
||||
@@ -211,7 +253,9 @@ impl Activity {
|
||||
now >= self.eligible_at
|
||||
&& match self.state {
|
||||
State::Running => self.lease_deadline.is_none_or(|deadline| now < deadline),
|
||||
State::Done | State::Failed => !dnd && self.result_deadline.is_some_and(|deadline| now < deadline),
|
||||
State::Done | State::Failed => {
|
||||
!dnd && self.result_deadline.is_some_and(|deadline| now < deadline)
|
||||
}
|
||||
State::Cancelled => false,
|
||||
}
|
||||
}
|
||||
@@ -258,7 +302,9 @@ impl Store {
|
||||
}
|
||||
|
||||
pub fn resolve(&self, owner: Owner, local: &str) -> Option<&Id> {
|
||||
self.entries.keys().find(|id| id.owner == owner && id.local == local)
|
||||
self.entries
|
||||
.keys()
|
||||
.find(|id| id.owner == owner && id.local == local)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@@ -290,7 +336,10 @@ impl Store {
|
||||
if self.entries.keys().filter(|id| id.owner == owner).count() >= 3 {
|
||||
return Err("owner activity quota exceeded");
|
||||
}
|
||||
self.generation = self.generation.checked_add(1).ok_or("generation exhausted")?;
|
||||
self.generation = self
|
||||
.generation
|
||||
.checked_add(1)
|
||||
.ok_or("generation exhausted")?;
|
||||
let id = Id {
|
||||
owner,
|
||||
local,
|
||||
@@ -351,7 +400,8 @@ impl Store {
|
||||
validate_lease(Some(ms), true)?;
|
||||
entry.lease_deadline = Some(now.saturating_add(ms));
|
||||
} else if let Some(deadline) = entry.lease_deadline {
|
||||
entry.lease_deadline = Some(now.saturating_add(deadline.saturating_sub(entry.refreshed_at)));
|
||||
entry.lease_deadline =
|
||||
Some(now.saturating_add(deadline.saturating_sub(entry.refreshed_at)));
|
||||
}
|
||||
entry.refreshed_at = now;
|
||||
Ok(())
|
||||
@@ -380,7 +430,10 @@ impl Store {
|
||||
Err("terminal result already accepted")
|
||||
};
|
||||
}
|
||||
if state == State::Cancelled || now < entry.eligible_at || (state == State::Failed && !entry.flash_on_fail) {
|
||||
if state == State::Cancelled
|
||||
|| now < entry.eligible_at
|
||||
|| (state == State::Failed && !entry.flash_on_fail)
|
||||
{
|
||||
self.entries.remove(id);
|
||||
return Ok(());
|
||||
}
|
||||
@@ -409,7 +462,11 @@ impl Store {
|
||||
|
||||
pub fn attach_output(&mut self, output: &str) -> bool {
|
||||
let mut changed = false;
|
||||
for entry in self.entries.values_mut().filter(|entry| entry.data.output.is_none()) {
|
||||
for entry in self
|
||||
.entries
|
||||
.values_mut()
|
||||
.filter(|entry| entry.data.output.is_none())
|
||||
{
|
||||
entry.data.output = Some(output.into());
|
||||
changed = true;
|
||||
}
|
||||
@@ -433,9 +490,11 @@ impl Store {
|
||||
Some(entry.eligible_at.saturating_add(BOOST_MS)),
|
||||
entry.lease_deadline,
|
||||
entry.result_deadline,
|
||||
entry
|
||||
.result_deadline
|
||||
.map(|deadline| deadline.saturating_sub(entry.result_flash_ms).saturating_add(400)),
|
||||
entry.result_deadline.map(|deadline| {
|
||||
deadline
|
||||
.saturating_sub(entry.result_flash_ms)
|
||||
.saturating_add(400)
|
||||
}),
|
||||
]
|
||||
})
|
||||
.flatten()
|
||||
@@ -497,7 +556,13 @@ impl Selection {
|
||||
pub fn override_pin(&mut self) {
|
||||
self.pinned = None;
|
||||
}
|
||||
pub fn select(&mut self, ranked: &[&Activity], limits: Limits, dnd: bool, protected_slots: usize) {
|
||||
pub fn select(
|
||||
&mut self,
|
||||
ranked: &[&Activity],
|
||||
limits: Limits,
|
||||
dnd: bool,
|
||||
protected_slots: usize,
|
||||
) {
|
||||
let policy = (dnd, protected_slots, limits.max_visible);
|
||||
if self.policy != Some(policy) {
|
||||
self.override_pin();
|
||||
@@ -557,7 +622,9 @@ pub fn reconcile_focus(focus: &mut Option<Id>, previous: &[Id], current: &[Id])
|
||||
.as_ref()
|
||||
.and_then(|id| previous.iter().position(|old| old == id))
|
||||
.unwrap_or(0);
|
||||
*focus = current.get(index.min(current.len().saturating_sub(1))).cloned();
|
||||
*focus = current
|
||||
.get(index.min(current.len().saturating_sub(1)))
|
||||
.cloned();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -131,7 +131,11 @@ impl Session {
|
||||
if let Some(phase) = phase {
|
||||
self.phase = phase;
|
||||
self.remaining_ms = self.settings.duration(phase);
|
||||
self.status = if running { Status::Running } else { Status::Ready };
|
||||
self.status = if running {
|
||||
Status::Running
|
||||
} else {
|
||||
Status::Ready
|
||||
};
|
||||
if running {
|
||||
self.deadline = Some(now.saturating_add(self.remaining_ms));
|
||||
}
|
||||
@@ -210,7 +214,13 @@ mod tests {
|
||||
] {
|
||||
let deadline = session.deadline.unwrap();
|
||||
assert!(session.advance(deadline - 1).is_none());
|
||||
assert_eq!(session.advance(deadline), Some(Completion { phase: finished, next }));
|
||||
assert_eq!(
|
||||
session.advance(deadline),
|
||||
Some(Completion {
|
||||
phase: finished,
|
||||
next
|
||||
})
|
||||
);
|
||||
assert_eq!(session.completed_work, count);
|
||||
assert!(session.advance(deadline + 99_000_000).is_none());
|
||||
if next.is_some() {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use super::*;
|
||||
|
||||
fn owner() -> Owner {
|
||||
Owner { pid: 42, birth: 100 }
|
||||
Owner {
|
||||
pid: 42,
|
||||
birth: 100,
|
||||
}
|
||||
}
|
||||
fn data(priority: u8) -> Data {
|
||||
Data {
|
||||
@@ -84,9 +87,21 @@ fn fast_failures_cancel_and_suppressed_failure_never_flash() {
|
||||
}
|
||||
let mut store = Store::new(1);
|
||||
let id = store
|
||||
.start(owner(), "a".into(), data(100), 0, 0, None, true, false, None)
|
||||
.start(
|
||||
owner(),
|
||||
"a".into(),
|
||||
data(100),
|
||||
0,
|
||||
0,
|
||||
None,
|
||||
true,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
store
|
||||
.finish(owner(), &id, State::Failed, None, 300)
|
||||
.unwrap();
|
||||
store.finish(owner(), &id, State::Failed, None, 300).unwrap();
|
||||
assert_eq!(store.entries().count(), 0);
|
||||
}
|
||||
|
||||
@@ -98,7 +113,9 @@ fn result_retry_and_owner_exit_preserve_original_deadline() {
|
||||
.finish(owner(), &id, State::Failed, Some("Failed".into()), 300)
|
||||
.unwrap();
|
||||
assert_eq!(store.entries().next().unwrap().score(300, 255), 385);
|
||||
store.finish(owner(), &id, State::Failed, None, 1_000).unwrap();
|
||||
store
|
||||
.finish(owner(), &id, State::Failed, None, 1_000)
|
||||
.unwrap();
|
||||
store.owner_exit(owner());
|
||||
assert_eq!(store.entries().next().unwrap().result_deadline, Some(1_800));
|
||||
assert!(!store.advance(1_799));
|
||||
@@ -110,7 +127,17 @@ fn result_retry_and_owner_exit_preserve_original_deadline() {
|
||||
fn leases_refresh_but_abandonment_never_claims_a_result() {
|
||||
let mut store = Store::new(1);
|
||||
let id = store
|
||||
.start(owner(), "a".into(), data(100), 0, 0, Some(500), false, true, None)
|
||||
.start(
|
||||
owner(),
|
||||
"a".into(),
|
||||
data(100),
|
||||
0,
|
||||
0,
|
||||
Some(500),
|
||||
false,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
store.update(owner(), &id, None, None, 499).unwrap();
|
||||
assert_eq!(store.entries().next().unwrap().lease_deadline, Some(999));
|
||||
@@ -132,7 +159,10 @@ fn leases_refresh_but_abandonment_never_claims_a_result() {
|
||||
fn owner_session_generation_and_quotas_are_independent_of_connections() {
|
||||
let mut store = Store::new(12);
|
||||
let id = start(&mut store, "a", 0, 100);
|
||||
let other = Owner { pid: 42, birth: 101 };
|
||||
let other = Owner {
|
||||
pid: 42,
|
||||
birth: 101,
|
||||
};
|
||||
assert!(store.update(other, &id, None, None, 0).is_err());
|
||||
let mut stale = id.clone();
|
||||
stale.session = 11;
|
||||
@@ -149,7 +179,9 @@ fn owner_session_generation_and_quotas_are_independent_of_connections() {
|
||||
.start(owner(), "d".into(), data(100), 0, 0, None, true, true, None)
|
||||
.is_err()
|
||||
);
|
||||
store.finish(owner(), &id, State::Cancelled, None, 0).unwrap();
|
||||
store
|
||||
.finish(owner(), &id, State::Cancelled, None, 0)
|
||||
.unwrap();
|
||||
let replacement = start(&mut store, "a", 0, 100);
|
||||
assert_ne!(replacement.generation, id.generation);
|
||||
assert!(store.update(owner(), &id, None, None, 0).is_err());
|
||||
@@ -215,7 +247,10 @@ fn dnd_protected_slots_and_output_routing() {
|
||||
assert_eq!(selection.hidden, 2);
|
||||
store.remove_output("one", Some("two"));
|
||||
assert!(ranked(store.entries(), 300, store.limits, "one", false).is_empty());
|
||||
assert_eq!(ranked(store.entries(), 300, store.limits, "two", false).len(), 2);
|
||||
assert_eq!(
|
||||
ranked(store.entries(), 300, store.limits, "two", false).len(),
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -280,9 +315,21 @@ fn notification_boost_cannot_outrank_ordinary_and_grouped_lifetimes_remain_indep
|
||||
let mut notification = data(255);
|
||||
notification.source = Source::Notification;
|
||||
let notice = store
|
||||
.start(owner(), "notice".into(), notification, 0, 0, None, true, true, None)
|
||||
.start(
|
||||
owner(),
|
||||
"notice".into(),
|
||||
notification,
|
||||
0,
|
||||
0,
|
||||
None,
|
||||
true,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
store
|
||||
.finish(owner(), ¬ice, State::Failed, None, 300)
|
||||
.unwrap();
|
||||
store.finish(owner(), ¬ice, State::Failed, None, 300).unwrap();
|
||||
let entries = ranked(store.entries(), 300, store.limits, "one", false);
|
||||
assert_eq!(entries.last().unwrap().id, notice);
|
||||
let mut selection = Selection::default();
|
||||
@@ -298,14 +345,27 @@ fn notification_boost_cannot_outrank_ordinary_and_grouped_lifetimes_remain_indep
|
||||
);
|
||||
store.remove_output("one", None);
|
||||
assert!(store.attach_output("two"));
|
||||
assert_eq!(ranked(store.entries(), 301, store.limits, "two", false).len(), 3);
|
||||
assert_eq!(
|
||||
ranked(store.entries(), 301, store.limits, "two", false).len(),
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_updates_are_atomic_and_suspend_aware_eligibility_hides_expired_records() {
|
||||
let mut store = Store::new(1);
|
||||
let id = store
|
||||
.start(owner(), "atomic".into(), data(100), 0, 0, Some(1_000), true, true, None)
|
||||
.start(
|
||||
owner(),
|
||||
"atomic".into(),
|
||||
data(100),
|
||||
0,
|
||||
0,
|
||||
Some(1_000),
|
||||
true,
|
||||
true,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
store
|
||||
|
||||
Reference in new issue
Block a user