refactor(review): shell current-thread runtime + единый дефолт; PowerClient parse_enum; тесты на ipc::names
- shell: new_current_thread рантайм (без пула на холодном старте, #11); единый Initial::default(). - PowerClient: generic parse_enum (убрал 3 копии map_err). - ipc::names::power::MOCK_IFACE; интеграционные тесты — через ipc::names (не хардкод). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Alexander <akotenev2003@gmail.com>
This commit is contained in:
@@ -83,7 +83,11 @@ impl Default for Initial {
|
|||||||
|
|
||||||
/// Одноразовое чтение состояния с шины (best-effort). Без шины/сервисов — дефолты (#4).
|
/// Одноразовое чтение состояния с шины (best-effort). Без шины/сервисов — дефолты (#4).
|
||||||
fn read_initial() -> Initial {
|
fn read_initial() -> Initial {
|
||||||
let rt = match tokio::runtime::Runtime::new() {
|
// current-thread рантайм: одно best-effort чтение на холодном старте, без пула потоков (#11).
|
||||||
|
let rt = match tokio::runtime::Builder::new_current_thread()
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
{
|
||||||
Ok(rt) => rt,
|
Ok(rt) => rt,
|
||||||
Err(_) => return Initial::default(),
|
Err(_) => return Initial::default(),
|
||||||
};
|
};
|
||||||
@@ -99,6 +103,7 @@ fn read_initial() -> Initial {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn connect_and_read() -> anyhow::Result<Initial> {
|
async fn connect_and_read() -> anyhow::Result<Initial> {
|
||||||
|
let def = Initial::default(); // единый источник дефолтов (без дублей литералов)
|
||||||
let conn = shturman_sdk::connect().await?;
|
let conn = shturman_sdk::connect().await?;
|
||||||
let settings = shturman_sdk::SettingsClient::new(&conn).await?;
|
let settings = shturman_sdk::SettingsClient::new(&conn).await?;
|
||||||
let theme = settings
|
let theme = settings
|
||||||
@@ -106,17 +111,17 @@ async fn connect_and_read() -> anyhow::Result<Initial> {
|
|||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|v| String::try_from(v).ok())
|
.and_then(|v| String::try_from(v).ok())
|
||||||
.unwrap_or_else(|| "auto".into());
|
.unwrap_or(def.theme);
|
||||||
let power = shturman_sdk::PowerClient::new(&conn).await?;
|
let power = shturman_sdk::PowerClient::new(&conn).await?;
|
||||||
let ignition = power
|
let ignition = power
|
||||||
.ignition_state()
|
.ignition_state()
|
||||||
.await
|
.await
|
||||||
.map(|i| i.as_str().to_string())
|
.map(|i| i.as_str().to_string())
|
||||||
.unwrap_or_else(|_| "unknown".into());
|
.unwrap_or(def.ignition);
|
||||||
Ok(Initial {
|
Ok(Initial {
|
||||||
theme,
|
theme,
|
||||||
ignition,
|
ignition,
|
||||||
network: "unknown".into(),
|
network: def.network,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
//! Проверяет state по шине и fake-ACC: `dev.PowerMock1.SetAcc` → сигнал `Power1.AccChanged`.
|
//! Проверяет state по шине и fake-ACC: `dev.PowerMock1.SetAcc` → сигнал `Power1.AccChanged`.
|
||||||
|
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use shturman_ipc::types::PowerState;
|
use shturman_ipc::{names, types::PowerState};
|
||||||
use shturman_power::PowerService;
|
use shturman_power::PowerService;
|
||||||
use shturman_sdk::PowerClient;
|
use shturman_sdk::PowerClient;
|
||||||
|
|
||||||
@@ -16,15 +16,15 @@ async fn power_state_and_fake_acc() {
|
|||||||
let server = zbus::Connection::session().await.unwrap();
|
let server = zbus::Connection::session().await.unwrap();
|
||||||
server
|
server
|
||||||
.object_server()
|
.object_server()
|
||||||
.at("/ru/shturman/Power", svc)
|
.at(names::power::PATH, svc)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server
|
server
|
||||||
.object_server()
|
.object_server()
|
||||||
.at("/ru/shturman/Power", mock)
|
.at(names::power::PATH, mock)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server.request_name("ru.shturman.Power").await.unwrap();
|
server.request_name(names::power::NAME).await.unwrap();
|
||||||
|
|
||||||
let client_conn = zbus::Connection::session().await.unwrap();
|
let client_conn = zbus::Connection::session().await.unwrap();
|
||||||
let power = PowerClient::new(&client_conn).await.unwrap();
|
let power = PowerClient::new(&client_conn).await.unwrap();
|
||||||
@@ -36,9 +36,9 @@ async fn power_state_and_fake_acc() {
|
|||||||
// dev.PowerMock1.SetAcc(false) сырым D-Bus-вызовом
|
// dev.PowerMock1.SetAcc(false) сырым D-Bus-вызовом
|
||||||
client_conn
|
client_conn
|
||||||
.call_method(
|
.call_method(
|
||||||
Some("ru.shturman.Power"),
|
Some(names::power::NAME),
|
||||||
"/ru/shturman/Power",
|
names::power::PATH,
|
||||||
Some("ru.shturman.dev.PowerMock1"),
|
Some(names::power::MOCK_IFACE),
|
||||||
"SetAcc",
|
"SetAcc",
|
||||||
&(false,),
|
&(false,),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use shturman_common::Layout;
|
use shturman_common::Layout;
|
||||||
|
use shturman_ipc::names;
|
||||||
use shturman_sdk::SettingsClient;
|
use shturman_sdk::SettingsClient;
|
||||||
use shturman_settings::{store::Store, SettingsService};
|
use shturman_settings::{store::Store, SettingsService};
|
||||||
use zbus::zvariant::Value;
|
use zbus::zvariant::Value;
|
||||||
@@ -17,10 +18,10 @@ async fn settings_round_trip_and_changed() {
|
|||||||
let server = zbus::Connection::session().await.unwrap();
|
let server = zbus::Connection::session().await.unwrap();
|
||||||
server
|
server
|
||||||
.object_server()
|
.object_server()
|
||||||
.at("/ru/shturman/Settings", SettingsService::new(store))
|
.at(names::settings::PATH, SettingsService::new(store))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
server.request_name("ru.shturman.Settings").await.unwrap();
|
server.request_name(names::settings::NAME).await.unwrap();
|
||||||
|
|
||||||
// клиент на отдельном соединении
|
// клиент на отдельном соединении
|
||||||
let client_conn = zbus::Connection::session().await.unwrap();
|
let client_conn = zbus::Connection::session().await.unwrap();
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ pub mod power {
|
|||||||
pub const NAME: &str = "ru.shturman.Power";
|
pub const NAME: &str = "ru.shturman.Power";
|
||||||
pub const PATH: &str = "/ru/shturman/Power";
|
pub const PATH: &str = "/ru/shturman/Power";
|
||||||
pub const IFACE: &str = "ru.shturman.Power1";
|
pub const IFACE: &str = "ru.shturman.Power1";
|
||||||
|
/// dev-mock «fake-ACC» (интерфейс на том же объекте; только dev-сборка).
|
||||||
|
pub const MOCK_IFACE: &str = "ru.shturman.dev.PowerMock1";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod settings {
|
pub mod settings {
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ use shturman_ipc::proxy::Power1Proxy;
|
|||||||
use shturman_ipc::types::{IgnitionState, PowerSource, PowerState};
|
use shturman_ipc::types::{IgnitionState, PowerSource, PowerState};
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
|
/// Распарсить enum-строку с провода; неизвестное значение → zbus-ошибка с меткой типа.
|
||||||
|
fn parse_enum<T: FromStr>(label: &str, raw: String) -> zbus::Result<T> {
|
||||||
|
T::from_str(&raw).map_err(|_| zbus::Error::Failure(format!("unknown {label}: {raw}")))
|
||||||
|
}
|
||||||
|
|
||||||
/// Эргономичный клиент `ru.shturman.Power`.
|
/// Эргономичный клиент `ru.shturman.Power`.
|
||||||
pub struct PowerClient {
|
pub struct PowerClient {
|
||||||
proxy: Power1Proxy<'static>,
|
proxy: Power1Proxy<'static>,
|
||||||
@@ -18,21 +23,15 @@ impl PowerClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn power_state(&self) -> zbus::Result<PowerState> {
|
pub async fn power_state(&self) -> zbus::Result<PowerState> {
|
||||||
let s = self.proxy.get_power_state().await?;
|
parse_enum("PowerState", self.proxy.get_power_state().await?)
|
||||||
PowerState::from_str(&s)
|
|
||||||
.map_err(|_| zbus::Error::Failure(format!("unknown PowerState: {s}")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn ignition_state(&self) -> zbus::Result<IgnitionState> {
|
pub async fn ignition_state(&self) -> zbus::Result<IgnitionState> {
|
||||||
let s = self.proxy.ignition_state().await?;
|
parse_enum("IgnitionState", self.proxy.ignition_state().await?)
|
||||||
IgnitionState::from_str(&s)
|
|
||||||
.map_err(|_| zbus::Error::Failure(format!("unknown IgnitionState: {s}")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn power_source(&self) -> zbus::Result<PowerSource> {
|
pub async fn power_source(&self) -> zbus::Result<PowerSource> {
|
||||||
let s = self.proxy.power_source().await?;
|
parse_enum("PowerSource", self.proxy.power_source().await?)
|
||||||
PowerSource::from_str(&s)
|
|
||||||
.map_err(|_| zbus::Error::Failure(format!("unknown PowerSource: {s}")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn uptime(&self) -> zbus::Result<u64> {
|
pub async fn uptime(&self) -> zbus::Result<u64> {
|
||||||
|
|||||||
Reference in New Issue
Block a user