max / goingson
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01MptwXZ8k65v19rFmdGAyki
5 files changed,
+57 insertions,
-80 deletions
| @@ -266,14 +266,9 @@ | |||
| 266 | 266 | } | |
| 267 | 267 | } | |
| 268 | 268 | ||
| 269 | - | /// Whether an account has been chosen. R9: read whether or not it is placed. | |
| 270 | - | fn has_from(loaded: &Loaded) -> bool { | |
| 271 | - | loaded.from.is_some() | |
| 272 | - | } | |
| 273 | - | ||
| 274 | - | /// That account's id, or nothing. | |
| 275 | - | fn from_value(loaded: &Loaded) -> &str { | |
| 276 | - | loaded.from.as_deref().unwrap_or_default() | |
| 269 | + | /// The account the message is sent from, once one is chosen. | |
| 270 | + | fn from_value(loaded: &Loaded) -> Option<&str> { | |
| 271 | + | loaded.from.as_deref() | |
| 277 | 272 | } | |
| 278 | 273 | ||
| 279 | 274 | /// Whether the message carries nothing. | |
| @@ -344,7 +339,9 @@ | |||
| 344 | 339 | ||
| 345 | 340 | field Select FROM "From" { | |
| 346 | 341 | options loaded.accounts.clone(); | |
| 347 | - | value from_value(loaded) when has_from(loaded); | |
| 342 | + | for from in from_value(loaded).into_iter() { | |
| 343 | + | value from; | |
| 344 | + | } | |
| 348 | 345 | writes field_route(loaded.id, FROM); | |
| 349 | 346 | } | |
| 350 | 347 |
| @@ -275,33 +275,26 @@ | |||
| 275 | 275 | } | |
| 276 | 276 | } | |
| 277 | 277 | ||
| 278 | - | /// The label a stored context holds. | |
| 279 | - | fn stored_label(editing: &Editing) -> String { | |
| 280 | - | editing | |
| 281 | - | .existing | |
| 282 | - | .map(|context| context.label.clone()) | |
| 283 | - | .unwrap_or_default() | |
| 278 | + | /// The label a stored context holds, if the pane is editing one. | |
| 279 | + | fn stored_label(editing: &Editing) -> Option<String> { | |
| 280 | + | editing.existing.map(|context| context.label.clone()) | |
| 284 | 281 | } | |
| 285 | 282 | ||
| 286 | 283 | /// The kind a stored context holds, as it is stored. | |
| 287 | - | fn stored_kind<'a>(editing: &Editing<'a>) -> &'a str { | |
| 288 | - | editing.existing.map_or("", |context| context.kind.as_str()) | |
| 284 | + | fn stored_kind<'a>(editing: &Editing<'a>) -> Option<&'a str> { | |
| 285 | + | editing.existing.map(|context| context.kind.as_str()) | |
| 289 | 286 | } | |
| 290 | 287 | ||
| 291 | 288 | /// The first day a stored context holds. | |
| 292 | - | fn stored_start(editing: &Editing) -> String { | |
| 289 | + | fn stored_start(editing: &Editing) -> Option<String> { | |
| 293 | 290 | editing | |
| 294 | 291 | .existing | |
| 295 | 292 | .map(|context| context.starts_on.to_string()) | |
| 296 | - | .unwrap_or_default() | |
| 297 | 293 | } | |
| 298 | 294 | ||
| 299 | 295 | /// The last day a stored context holds. | |
| 300 | - | fn stored_end(editing: &Editing) -> String { | |
| 301 | - | editing | |
| 302 | - | .existing | |
| 303 | - | .map(|context| context.ends_on.to_string()) | |
| 304 | - | .unwrap_or_default() | |
| 296 | + | fn stored_end(editing: &Editing) -> Option<String> { | |
| 297 | + | editing.existing.map(|context| context.ends_on.to_string()) | |
| 305 | 298 | } | |
| 306 | 299 | ||
| 307 | 300 | /// Whether a named field was refused. | |
| @@ -358,7 +351,9 @@ | |||
| 358 | 351 | field Text "label" "Label" { | |
| 359 | 352 | required; | |
| 360 | 353 | placeholder "Two weeks in Lisbon"; | |
| 361 | - | value stored_label(editing) when is_edit(editing); | |
| 354 | + | for label in stored_label(editing).into_iter() { | |
| 355 | + | value label; | |
| 356 | + | } | |
| 362 | 357 | error error_for(editing, "label") when has_error(editing, "label"); | |
| 363 | 358 | refilled typed(editing); | |
| 364 | 359 | } | |
| @@ -367,7 +362,9 @@ | |||
| 367 | 362 | for kind in KINDS.iter().copied() { | |
| 368 | 363 | option Choice::new(kind.as_str(), kind_label(kind)); | |
| 369 | 364 | } | |
| 370 | - | value stored_kind(editing) when is_edit(editing); | |
| 365 | + | for kind in stored_kind(editing).into_iter() { | |
| 366 | + | value kind; | |
| 367 | + | } | |
| 371 | 368 | error error_for(editing, "kind") when has_error(editing, "kind"); | |
| 372 | 369 | refilled typed(editing); | |
| 373 | 370 | } | |
| @@ -375,7 +372,9 @@ | |||
| 375 | 372 | field Date "starts_on" "First day" { | |
| 376 | 373 | required; | |
| 377 | 374 | hint "The first day inside it."; | |
| 378 | - | value stored_start(editing) when is_edit(editing); | |
| 375 | + | for start in stored_start(editing).into_iter() { | |
| 376 | + | value start; | |
| 377 | + | } | |
| 379 | 378 | error error_for(editing, "starts_on") when has_error(editing, "starts_on"); | |
| 380 | 379 | refilled typed(editing); | |
| 381 | 380 | } | |
| @@ -383,7 +382,9 @@ | |||
| 383 | 382 | field Date "ends_on" "Last day" { | |
| 384 | 383 | required; | |
| 385 | 384 | hint "Inclusive: off until the 17th means the 17th is off."; | |
| 386 | - | value stored_end(editing) when is_edit(editing); | |
| 385 | + | for end in stored_end(editing).into_iter() { | |
| 386 | + | value end; | |
| 387 | + | } | |
| 387 | 388 | error error_for(editing, "ends_on") when has_error(editing, "ends_on"); | |
| 388 | 389 | refilled typed(editing); | |
| 389 | 390 | } |
| @@ -273,15 +273,9 @@ | |||
| 273 | 273 | listed.problem.painhours().to_string() | |
| 274 | 274 | } | |
| 275 | 275 | ||
| 276 | - | /// Whether the problem belongs to a project. R9: read whether or not the badge | |
| 277 | - | /// is placed. | |
| 278 | - | fn has_project(listed: &Listed) -> bool { | |
| 279 | - | listed.project.is_some() | |
| 280 | - | } | |
| 281 | - | ||
| 282 | - | /// That project's name, or nothing. | |
| 283 | - | fn project_name(listed: &Listed) -> &str { | |
| 284 | - | listed.project.as_deref().unwrap_or_default() | |
| 276 | + | /// The project the problem belongs to, if it belongs to one. | |
| 277 | + | fn project_name(listed: &Listed) -> Option<&str> { | |
| 278 | + | listed.project.as_deref() | |
| 285 | 279 | } | |
| 286 | 280 | ||
| 287 | 281 | /// Where the score came from, and how old the report is. | |
| @@ -380,7 +374,9 @@ | |||
| 380 | 374 | &listed.problem.source, | |
| 381 | 375 | list_action(listing.status, Some(&listed.problem.source)) | |
| 382 | 376 | ); | |
| 383 | - | token Tag::badge(project_name(listed)).tone(Tone::Info) when has_project(listed); | |
| 377 | + | for project in project_name(listed).into_iter() { | |
| 378 | + | token Tag::badge(project).tone(Tone::Info); | |
| 379 | + | } | |
| 384 | 380 | token Tag::badge(listed.problem.status.as_str()) | |
| 385 | 381 | .tone(status_tone(listed.problem.status)) | |
| 386 | 382 | when listed.problem.status.is_settled(); |
| @@ -1063,32 +1063,17 @@ | |||
| 1063 | 1063 | listing.view.priority.as_ref() == Some(priority) | |
| 1064 | 1064 | } | |
| 1065 | 1065 | ||
| 1066 | - | /// The project the filter is on. | |
| 1067 | - | fn project_value(listing: &Listing) -> String { | |
| 1068 | - | listing | |
| 1069 | - | .view | |
| 1070 | - | .project | |
| 1071 | - | .map(|project| project.to_string()) | |
| 1072 | - | .unwrap_or_default() | |
| 1066 | + | /// The project the filter is on, if it is on one. | |
| 1067 | + | fn project_value(listing: &Listing) -> Option<String> { | |
| 1068 | + | listing.view.project.map(|project| project.to_string()) | |
| 1073 | 1069 | } | |
| 1074 | 1070 | ||
| 1075 | - | /// Whether one is. | |
| 1076 | - | fn has_project(listing: &Listing) -> bool { | |
| 1077 | - | listing.view.project.is_some() | |
| 1078 | - | } | |
| 1079 | - | ||
| 1080 | - | /// The milestone the filter is on. | |
| 1081 | - | fn milestone_value(listing: &Listing) -> String { | |
| 1071 | + | /// The milestone the filter is on, if it is on one. | |
| 1072 | + | fn milestone_value(listing: &Listing) -> Option<String> { | |
| 1082 | 1073 | listing | |
| 1083 | 1074 | .view | |
| 1084 | 1075 | .milestone | |
| 1085 | 1076 | .map(|milestone| milestone.to_string()) | |
| 1086 | - | .unwrap_or_default() | |
| 1087 | - | } | |
| 1088 | - | ||
| 1089 | - | /// Whether one is. | |
| 1090 | - | fn has_milestone(listing: &Listing) -> bool { | |
| 1091 | - | listing.view.milestone.is_some() | |
| 1092 | 1077 | } | |
| 1093 | 1078 | ||
| 1094 | 1079 | declare! { | |
| @@ -1116,13 +1101,17 @@ | |||
| 1116 | 1101 | field Select "project" "Project" unless listing.projects.is_empty() { | |
| 1117 | 1102 | options listing.projects.clone(); | |
| 1118 | 1103 | consulting Consult::at_once(listing.view.clearing_project().list()); | |
| 1119 | - | value project_value(listing) when has_project(listing); | |
| 1104 | + | for project in project_value(listing).into_iter() { | |
| 1105 | + | value project; | |
| 1106 | + | } | |
| 1120 | 1107 | } | |
| 1121 | 1108 | ||
| 1122 | 1109 | field Select "milestone" "Milestone" unless listing.milestones.is_empty() { | |
| 1123 | 1110 | options listing.milestones.clone(); | |
| 1124 | 1111 | consulting Consult::at_once(listing.view.clearing_milestone().list()); | |
| 1125 | - | value milestone_value(listing) when has_milestone(listing); | |
| 1112 | + | for milestone in milestone_value(listing).into_iter() { | |
| 1113 | + | value milestone; | |
| 1114 | + | } | |
| 1126 | 1115 | } | |
| 1127 | 1116 | ||
| 1128 | 1117 | for offered in PRIORITIES { |
| @@ -128,24 +128,14 @@ | |||
| 128 | 128 | } | |
| 129 | 129 | } | |
| 130 | 130 | ||
| 131 | - | /// Whether the server is named. R9: read whether or not the row is placed. | |
| 132 | - | fn has_server(state: &State) -> bool { | |
| 133 | - | !server(state).is_empty() | |
| 131 | + | /// The server this device syncs with, once it knows one. | |
| 132 | + | fn server(state: &State) -> Option<&str> { | |
| 133 | + | state.server_url.as_deref().filter(|url| !url.is_empty()) | |
| 134 | 134 | } | |
| 135 | 135 | ||
| 136 | - | /// That server, or nothing. | |
| 137 | - | fn server(state: &State) -> &str { | |
| 138 | - | state.server_url.as_deref().unwrap_or_default() | |
| 139 | - | } | |
| 140 | - | ||
| 141 | - | /// Whether this device has an id yet. | |
| 142 | - | fn has_device(state: &State) -> bool { | |
| 143 | - | !device(state).is_empty() | |
| 144 | - | } | |
| 145 | - | ||
| 146 | - | /// That id, or nothing. | |
| 147 | - | fn device(state: &State) -> &str { | |
| 148 | - | state.device_id.as_deref().unwrap_or_default() | |
| 136 | + | /// This device's id, once it has one. | |
| 137 | + | fn device(state: &State) -> Option<&str> { | |
| 138 | + | state.device_id.as_deref().filter(|id| !id.is_empty()) | |
| 149 | 139 | } | |
| 150 | 140 | ||
| 151 | 141 | /// Signed in, or set up and not signed in. | |
| @@ -210,14 +200,18 @@ | |||
| 210 | 200 | row "Status" { | |
| 211 | 201 | meta status_label(&state); | |
| 212 | 202 | } | |
| 213 | - | row "Server" when has_server(&state) { | |
| 214 | - | meta server(&state); | |
| 203 | + | for server in server(&state).into_iter() { | |
| 204 | + | row "Server" { | |
| 205 | + | meta server; | |
| 206 | + | } | |
| 215 | 207 | } | |
| 216 | 208 | row "Encryption" { | |
| 217 | 209 | meta encryption_label(&state); | |
| 218 | 210 | } | |
| 219 | - | row "This device" when has_device(&state) { | |
| 220 | - | meta device(&state); | |
| 211 | + | for device in device(&state).into_iter() { | |
| 212 | + | row "This device" { | |
| 213 | + | meta device; | |
| 214 | + | } | |
| 221 | 215 | } | |
| 222 | 216 | row "Last sync" { | |
| 223 | 217 | meta last_sync(&state); |