diff --git a/crates/dtmm/src/controller/app.rs b/crates/dtmm/src/controller/app.rs index 88dee2e..b4b69ca 100644 --- a/crates/dtmm/src/controller/app.rs +++ b/crates/dtmm/src/controller/app.rs @@ -27,12 +27,25 @@ pub(crate) async fn import_mod(state: ActionState, info: FileInfo) -> Result, api: Arc) -> Result for ModDependency { pub(crate) struct NexusInfo { pub id: u64, pub version: String, + pub author: String, + pub summary: String, + pub description: Arc, +} + +impl From for NexusInfo { + fn from(value: NexusMod) -> Self { + Self { + id: value.mod_id, + version: value.version, + author: value.author, + summary: value.summary, + description: Arc::new(value.description), + } + } } #[derive(Clone, Data, Debug, Lens)] diff --git a/crates/dtmm/src/state/lens.rs b/crates/dtmm/src/state/lens.rs index 1156f52..c26c298 100644 --- a/crates/dtmm/src/state/lens.rs +++ b/crates/dtmm/src/state/lens.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use druid::im::Vector; use druid::{Data, Lens}; -use super::{ModInfo, State}; +use super::{ModInfo, NexusInfo, State}; pub(crate) struct SelectedModLens; @@ -73,3 +73,51 @@ impl Lens, Vector<(usize, T)>> for IndexedVectorLens { ret } } + +/// A Lens that first checks a key in a mod's `NexusInfo`, then falls back to +/// the regular one. +pub(crate) struct NexusInfoLens +where + L: Lens, + R: Lens, +{ + value: L, + fallback: R, + _marker: std::marker::PhantomData, +} + +impl NexusInfoLens +where + L: Lens, + R: Lens, +{ + pub fn new(value: L, fallback: R) -> Self { + Self { + value, + fallback, + _marker: std::marker::PhantomData, + } + } +} + +impl Lens for NexusInfoLens +where + L: Lens, + R: Lens, +{ + fn with V>(&self, data: &ModInfo, f: F) -> V { + if let Some(nexus) = &data.nexus { + self.value.with(nexus, f) + } else { + self.fallback.with(data, f) + } + } + + fn with_mut V>(&self, data: &mut ModInfo, f: F) -> V { + if let Some(nexus) = &mut data.nexus { + self.value.with_mut(nexus, f) + } else { + self.fallback.with_mut(data, f) + } + } +}