From 0728546a5c6072058fe996957365689d7ac90a1a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 6 Apr 2021 20:16:57 +0100 Subject: [PATCH] shapelib: Provide sort key information Signed-off-by: Ian Jackson --- src/shapelib-toml.rs | 16 +++++++++++++++- src/shapelib.rs | 21 +++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/shapelib-toml.rs b/src/shapelib-toml.rs index 99e180b2..9b9922eb 100644 --- a/src/shapelib-toml.rs +++ b/src/shapelib-toml.rs @@ -79,7 +79,11 @@ pub struct GroupDefn { /// adding fields to each line. This is done by adding a line at /// the start starting with `:` and then additing one additional /// whitespace separated value on each data line. Unknown - /// `fieldname` values are ignored. + /// `fieldname` values are ignored. Currently the extra fields + /// supported are: + /// + /// * `sort`: Specifies the sort key. See the `sort` group + /// definition property. /// /// The values for these extra fields come just before the /// dwscription, after the other whitespace-delimited fields, in the @@ -91,6 +95,16 @@ pub struct GroupDefn { #[serde(default)] pub item_prefix: String, #[serde(default)] pub item_suffix: String, + /// The sort key (used for item sorting in hands). + /// + /// If neither the group property, nor the `files` extra field, are + /// specified, the item name is used. + /// + /// If both are specified, the group property is used as a template. + /// `_s` is replaced by the sort extra field from the `files` list + /// `_c` is replaced by the colour, if applicable. + #[serde(default)] pub sort: String, + #[doc(hidden)] #[serde(flatten)] pub d: GroupDetails, } diff --git a/src/shapelib.rs b/src/shapelib.rs index 1f0443d1..ce7abd87 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -48,6 +48,7 @@ struct ItemDetails { #[derive(Debug,Clone)] struct ItemData { d: Arc, + sort: Option, group: Arc, outline: Outline, occ: OccData, @@ -164,6 +165,7 @@ struct FaceTransform { #[derive(Debug,Serialize,Deserialize)] pub struct Item { itemname: String, + sort: Option, faces: IndexVec, svgs: IndexVec, descs: IndexVec, @@ -451,7 +453,8 @@ impl Contents { }, }; - let it = Item { faces, descs, svgs, outline, back, + let sort = idata.sort.clone(); + let it = Item { faces, sort, descs, svgs, outline, back, itemname: name.to_string() }; (Box::new(it), occultable) } @@ -611,6 +614,13 @@ fn load_catalogue(libname: &str, dirname: &str, toml_path: &str) -> Contents { fe.item_spec, gdefn.item_suffix); let item_name: GoodItemName = item_name.try_into()?; + let sort = match (gdefn.sort.as_str(), fe.extra_fields.get("sort")) { + ("", None) => None, + (gd, None) => Some(gd.to_string()), + ("", Some(ef)) => Some(ef.to_string()), + (gd, Some(ef)) => Some(subst(gd, "_s", ef)?), + }; + let occ = match &group.d.occulted { None => OccData::None, Some(OccultationMethod::ByColour { colour }) => { @@ -635,7 +645,7 @@ fn load_catalogue(libname: &str, dirname: &str, toml_path: &str) -> Contents { }, }; - let mut add1 = |item_name: &GoodItemName, desc: &str| { + let mut add1 = |item_name: &GoodItemName, sort, desc: &str| { let desc = if let Some(desc_template) = &group.d.desc_template { subst(desc_template, "_desc", &desc)?.to_html() } else { @@ -645,6 +655,7 @@ fn load_catalogue(libname: &str, dirname: &str, toml_path: &str) -> Contents { group: group.clone(), occ: occ.clone(), outline: outline.clone(), + sort, d: Arc::new(ItemDetails { desc }), }; type H<'e,X,Y> = hash_map::Entry<'e,X,Y>; @@ -663,12 +674,14 @@ fn load_catalogue(libname: &str, dirname: &str, toml_path: &str) -> Contents { }; if group.d.colours.is_empty() { - add1(&item_name, &fe.desc.clone())?; + add1(&item_name, sort, &fe.desc.clone())?; } else { for (colour, recolourdata) in &group.d.colours { + let t_sort = sort.as_ref().map( + |s| subst(&s, "_c", colour)).transpose()?; let t_item_name = subst(item_name.as_str(), "_c", &recolourdata.abbrev)?; let t_desc = subst(&fe.desc, "_colour", colour)?; - add1(&t_item_name.try_into()?, &t_desc)?; + add1(&t_item_name.try_into()?, t_sort, &t_desc)?; } } -- 2.30.2