From 598cc85748f6a89ae5fb33f0800cefba9f96fb2d Mon Sep 17 00:00:00 2001 From: Peter Holloway Date: Wed, 12 Feb 2025 15:31:47 +0000 Subject: [PATCH] Support custom placeholders in templates --- src/graphql/mod.rs | 22 ++++++++++++++++++++++ src/paths.rs | 13 ++++++++----- static/service_schema.graphql | 7 ++++++- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/graphql/mod.rs b/src/graphql/mod.rs index 28963a6..9001ca1 100644 --- a/src/graphql/mod.rs +++ b/src/graphql/mod.rs @@ -14,6 +14,7 @@ use std::any; use std::borrow::Cow; +use std::collections::HashMap; use std::future::Future; use std::io::Write; use std::path::{Component, PathBuf}; @@ -145,6 +146,7 @@ struct DirectoryPath { struct ScanPaths { directory: DirectoryPath, subdirectory: Subdirectory, + metadata: HashMap, } /// GraphQL type to provide current configuration for an instrument @@ -153,6 +155,12 @@ struct CurrentConfiguration { high_file: Option, } +#[derive(Debug, InputObject)] +struct MetaKeyValue { + key: String, + value: String, +} + /// Error to be returned when a path contains non-unicode characters #[derive(Debug, Display, Error)] #[display("Path contains non-unicode characters")] @@ -308,6 +316,12 @@ impl FieldSource for ScanPaths { ScanField::Subdirectory => self.subdirectory.to_string().into(), ScanField::ScanNumber => self.directory.info.scan_number().to_string().into(), ScanField::Directory(dir) => self.directory.resolve(dir), + ScanField::Custom(key) => self + .metadata + .get(key) + .map(|s| s.as_str()) + .unwrap_or("") + .into(), } } } @@ -397,6 +411,7 @@ impl Mutation { instrument: String, instrument_session: String, sub: Option, + meta: Option>, ) -> async_graphql::Result { check_auth(ctx, |policy, token| { policy.check_access(token, &instrument, &instrument_session) @@ -420,11 +435,18 @@ impl Mutation { warn!("Failed to increment tracker file: {e}"); } + let metadata = meta + .into_iter() + .flatten() + .map(|kv| (kv.key, kv.value)) + .collect(); + Ok(ScanPaths { directory: DirectoryPath { instrument_session, info: next_scan, }, + metadata, subdirectory: sub.unwrap_or_default(), }) } diff --git a/src/paths.rs b/src/paths.rs index 3f0fa8b..a2ed681 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -32,7 +32,7 @@ pub enum DirectoryField { Instrument, } -#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Display, Clone, PartialEq, Eq, Hash)] pub enum ScanField { #[display("subdirectory")] Subdirectory, @@ -40,9 +40,11 @@ pub enum ScanField { ScanNumber, #[display("{_0}")] Directory(DirectoryField), + #[display("{_0}")] + Custom(String), } -#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Display, Clone, PartialEq, Eq, Hash)] pub enum DetectorField { #[display("detector")] Detector, @@ -73,7 +75,10 @@ impl TryFrom for ScanField { match value.as_str() { "scan_number" => Ok(ScanField::ScanNumber), "subdirectory" => Ok(ScanField::Subdirectory), - _ => Ok(ScanField::Directory(DirectoryField::try_from(value)?)), + _ => match DirectoryField::try_from(value) { + Ok(bf) => Ok(ScanField::Directory(bf)), + Err(InvalidKey(value)) => Ok(ScanField::Custom(value)), + }, } } } @@ -235,7 +240,6 @@ mod paths_tests { #[case::invalid_path_incomplete("data/{unclosed", TemplateErrorType::Incomplete)] #[case::invalid_path_empty("data/{}", TemplateErrorType::Empty)] #[case::invalid_path_nested("data/{nes{ted}}", TemplateErrorType::Nested)] - #[case::invalid_path_unrecognised("data/{detector}", TemplateErrorType::Unrecognised)] fn invalid_scan + Debug>( #[case] template: &str, #[case] err: E, @@ -251,7 +255,6 @@ mod paths_tests { #[case::invalid_path_incomplete("data/{unclosed", TemplateErrorType::Incomplete)] #[case::invalid_path_empty("data/{}", TemplateErrorType::Empty)] #[case::invalid_path_nested("data/{nes{ted}}", TemplateErrorType::Nested)] - #[case::invalid_path_unrecognised("data/{unknown}", TemplateErrorType::Unrecognised)] fn invalid_detector + Debug>( #[case] template: &str, #[case] err: E, diff --git a/static/service_schema.graphql b/static/service_schema.graphql index ddaf37f..2f740e2 100644 --- a/static/service_schema.graphql +++ b/static/service_schema.graphql @@ -112,6 +112,11 @@ A template describing the path to the data directory for a given instrument sess """ scalar DirectoryTemplate +input MetaKeyValue { + key: String! + value: String! +} + """ Queries that modify the state of the numtracker configuration in some way """ @@ -119,7 +124,7 @@ type Mutation { """ Generate scan file locations for the next scan """ - scan(instrument: String!, instrumentSession: String!, sub: Subdirectory): ScanPaths! + scan(instrument: String!, instrumentSession: String!, sub: Subdirectory, meta: [MetaKeyValue!]): ScanPaths! """ Add or modify the stored configuration for an instrument """