Skip to content

Commit 598cc85

Browse files
committed
Support custom placeholders in templates
1 parent 6bfa8c2 commit 598cc85

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

src/graphql/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
use std::any;
1616
use std::borrow::Cow;
17+
use std::collections::HashMap;
1718
use std::future::Future;
1819
use std::io::Write;
1920
use std::path::{Component, PathBuf};
@@ -145,6 +146,7 @@ struct DirectoryPath {
145146
struct ScanPaths {
146147
directory: DirectoryPath,
147148
subdirectory: Subdirectory,
149+
metadata: HashMap<String, String>,
148150
}
149151

150152
/// GraphQL type to provide current configuration for an instrument
@@ -153,6 +155,12 @@ struct CurrentConfiguration {
153155
high_file: Option<u32>,
154156
}
155157

158+
#[derive(Debug, InputObject)]
159+
struct MetaKeyValue {
160+
key: String,
161+
value: String,
162+
}
163+
156164
/// Error to be returned when a path contains non-unicode characters
157165
#[derive(Debug, Display, Error)]
158166
#[display("Path contains non-unicode characters")]
@@ -308,6 +316,12 @@ impl FieldSource<ScanField> for ScanPaths {
308316
ScanField::Subdirectory => self.subdirectory.to_string().into(),
309317
ScanField::ScanNumber => self.directory.info.scan_number().to_string().into(),
310318
ScanField::Directory(dir) => self.directory.resolve(dir),
319+
ScanField::Custom(key) => self
320+
.metadata
321+
.get(key)
322+
.map(|s| s.as_str())
323+
.unwrap_or("")
324+
.into(),
311325
}
312326
}
313327
}
@@ -397,6 +411,7 @@ impl Mutation {
397411
instrument: String,
398412
instrument_session: String,
399413
sub: Option<Subdirectory>,
414+
meta: Option<Vec<MetaKeyValue>>,
400415
) -> async_graphql::Result<ScanPaths> {
401416
check_auth(ctx, |policy, token| {
402417
policy.check_access(token, &instrument, &instrument_session)
@@ -420,11 +435,18 @@ impl Mutation {
420435
warn!("Failed to increment tracker file: {e}");
421436
}
422437

438+
let metadata = meta
439+
.into_iter()
440+
.flatten()
441+
.map(|kv| (kv.key, kv.value))
442+
.collect();
443+
423444
Ok(ScanPaths {
424445
directory: DirectoryPath {
425446
instrument_session,
426447
info: next_scan,
427448
},
449+
metadata,
428450
subdirectory: sub.unwrap_or_default(),
429451
})
430452
}

src/paths.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,19 @@ pub enum DirectoryField {
3232
Instrument,
3333
}
3434

35-
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash)]
35+
#[derive(Debug, Display, Clone, PartialEq, Eq, Hash)]
3636
pub enum ScanField {
3737
#[display("subdirectory")]
3838
Subdirectory,
3939
#[display("scan_number")]
4040
ScanNumber,
4141
#[display("{_0}")]
4242
Directory(DirectoryField),
43+
#[display("{_0}")]
44+
Custom(String),
4345
}
4446

45-
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash)]
47+
#[derive(Debug, Display, Clone, PartialEq, Eq, Hash)]
4648
pub enum DetectorField {
4749
#[display("detector")]
4850
Detector,
@@ -73,7 +75,10 @@ impl TryFrom<String> for ScanField {
7375
match value.as_str() {
7476
"scan_number" => Ok(ScanField::ScanNumber),
7577
"subdirectory" => Ok(ScanField::Subdirectory),
76-
_ => Ok(ScanField::Directory(DirectoryField::try_from(value)?)),
78+
_ => match DirectoryField::try_from(value) {
79+
Ok(bf) => Ok(ScanField::Directory(bf)),
80+
Err(InvalidKey(value)) => Ok(ScanField::Custom(value)),
81+
},
7782
}
7883
}
7984
}
@@ -235,7 +240,6 @@ mod paths_tests {
235240
#[case::invalid_path_incomplete("data/{unclosed", TemplateErrorType::Incomplete)]
236241
#[case::invalid_path_empty("data/{}", TemplateErrorType::Empty)]
237242
#[case::invalid_path_nested("data/{nes{ted}}", TemplateErrorType::Nested)]
238-
#[case::invalid_path_unrecognised("data/{detector}", TemplateErrorType::Unrecognised)]
239243
fn invalid_scan<E: PartialEq<InvalidPathTemplate> + Debug>(
240244
#[case] template: &str,
241245
#[case] err: E,
@@ -251,7 +255,6 @@ mod paths_tests {
251255
#[case::invalid_path_incomplete("data/{unclosed", TemplateErrorType::Incomplete)]
252256
#[case::invalid_path_empty("data/{}", TemplateErrorType::Empty)]
253257
#[case::invalid_path_nested("data/{nes{ted}}", TemplateErrorType::Nested)]
254-
#[case::invalid_path_unrecognised("data/{unknown}", TemplateErrorType::Unrecognised)]
255258
fn invalid_detector<E: PartialEq<InvalidPathTemplate> + Debug>(
256259
#[case] template: &str,
257260
#[case] err: E,

static/service_schema.graphql

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,19 @@ A template describing the path to the data directory for a given instrument sess
112112
"""
113113
scalar DirectoryTemplate
114114

115+
input MetaKeyValue {
116+
key: String!
117+
value: String!
118+
}
119+
115120
"""
116121
Queries that modify the state of the numtracker configuration in some way
117122
"""
118123
type Mutation {
119124
"""
120125
Generate scan file locations for the next scan
121126
"""
122-
scan(instrument: String!, instrumentSession: String!, sub: Subdirectory): ScanPaths!
127+
scan(instrument: String!, instrumentSession: String!, sub: Subdirectory, meta: [MetaKeyValue!]): ScanPaths!
123128
"""
124129
Add or modify the stored configuration for an instrument
125130
"""

0 commit comments

Comments
 (0)