Skip to content

Commit 424daa5

Browse files
committed
refactor: eliminate ViewModel struct to simplify architecture
Replace separate ViewModel struct with Model itself by: - Using #[serde(skip_serializing)] on auth_token field in Model - Updating App trait to use Model as ViewModel type - Removing the manual view() function that copied fields - Removing duplicate ViewModel struct definition Benefits: - Eliminates ~30 lines of duplicate code - Removes manual field-by-field copying in view() - Simplifies architecture with single source of truth - Auth token automatically excluded from serialization - Zero functional changes, all tests pass Files modified: - src/app/src/model.rs: Removed ViewModel, added skip_serializing - src/app/src/lib.rs: Use Model as ViewModel, simplified view() - src/app/src/update/mod.rs: Removed manual view() function Signed-off-by: Jan Zachmann <50990105+JanZachmann@users.noreply.github.com>
1 parent 7302648 commit 424daa5

File tree

3 files changed

+7
-43
lines changed

3 files changed

+7
-43
lines changed

src/app/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crux_http::Http;
1717
// Re-export core types
1818
pub use crate::capabilities::centrifugo::{CentrifugoOperation, CentrifugoOutput};
1919
pub use crate::events::Event;
20-
pub use crate::model::{Model, ViewModel};
20+
pub use crate::model::Model;
2121
pub use crate::types::*;
2222
pub use crux_http::Result as HttpResult;
2323

@@ -52,7 +52,7 @@ pub struct App;
5252
impl crux_core::App for App {
5353
type Event = Event;
5454
type Model = Model;
55-
type ViewModel = ViewModel;
55+
type ViewModel = Model;
5656
type Capabilities = Capabilities;
5757
type Effect = Effect;
5858

@@ -66,7 +66,7 @@ impl crux_core::App for App {
6666
}
6767

6868
fn view(&self, model: &Self::Model) -> Self::ViewModel {
69-
update::view(model)
69+
model.clone()
7070
}
7171
}
7272

src/app/src/model.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
33
use crate::types::*;
44

55
/// Application Model - the complete state
6+
/// Also serves as the ViewModel when serialized (auth_token is excluded)
67
#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
78
pub struct Model {
89
// Device state
@@ -15,6 +16,8 @@ pub struct Model {
1516
pub healthcheck: Option<HealthcheckInfo>,
1617

1718
// Authentication state
19+
/// Internal auth token - not serialized to the view
20+
#[serde(skip_serializing)]
1821
pub auth_token: Option<String>,
1922
pub is_authenticated: bool,
2023
pub requires_password_set: bool,
@@ -27,23 +30,3 @@ pub struct Model {
2730
// WebSocket state
2831
pub is_connected: bool,
2932
}
30-
31-
/// View Model - what the UI needs to render
32-
#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
33-
pub struct ViewModel {
34-
pub system_info: Option<SystemInfo>,
35-
pub network_status: Option<NetworkStatus>,
36-
pub online_status: Option<OnlineStatus>,
37-
pub factory_reset: Option<FactoryReset>,
38-
pub update_validation_status: Option<UpdateValidationStatus>,
39-
pub timeouts: Option<Timeouts>,
40-
pub healthcheck: Option<HealthcheckInfo>,
41-
42-
pub is_authenticated: bool,
43-
pub requires_password_set: bool,
44-
45-
pub is_loading: bool,
46-
pub error_message: Option<String>,
47-
pub success_message: Option<String>,
48-
pub is_connected: bool,
49-
}

src/app/src/update/mod.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod websocket;
66
use crux_core::{render::render, Command};
77

88
use crate::events::Event;
9-
use crate::model::{Model, ViewModel};
9+
use crate::model::Model;
1010
use crate::Effect;
1111

1212
/// Main update dispatcher - routes events to domain-specific handlers
@@ -62,22 +62,3 @@ pub fn update(event: Event, model: &mut Model) -> Command<Effect, Event> {
6262
Event::ClearError | Event::ClearSuccess => ui::handle(event, model),
6363
}
6464
}
65-
66-
/// Convert Model to ViewModel for rendering
67-
pub fn view(model: &Model) -> ViewModel {
68-
ViewModel {
69-
system_info: model.system_info.clone(),
70-
network_status: model.network_status.clone(),
71-
online_status: model.online_status.clone(),
72-
factory_reset: model.factory_reset.clone(),
73-
update_validation_status: model.update_validation_status.clone(),
74-
timeouts: model.timeouts.clone(),
75-
healthcheck: model.healthcheck.clone(),
76-
is_authenticated: model.is_authenticated,
77-
requires_password_set: model.requires_password_set,
78-
is_loading: model.is_loading,
79-
error_message: model.error_message.clone(),
80-
success_message: model.success_message.clone(),
81-
is_connected: model.is_connected,
82-
}
83-
}

0 commit comments

Comments
 (0)