Using serde_yaml with one or more strings and globset

I’m brand new to serde, and I’m having trouble figuring out how to accomplish a deserialize task at hand.

I have a YAML config file, with a map entry called ‘selection’. The value of this entry is either 1) a single string, or 2) a list of strings. Some examples:

selection: *.flac
----
selection:
    - *.mp3
    - *.jpg
    - *.mkv

I’d like to use serde_yaml to deserialize this config file (no serialization needed), process the one or more strings as glob patterns, and create a GlobSet object. However, I’m having trouble with figuring out the custom deserialization. I’ve found examples of both coercing single values and lists of values into lists, and converting a value to a new value, but not both together. How would I go about this?

Some issues I’ve faced:

  1. GlobSet isn’t deserializable, so I’d need to use custom deserialization logic.
  2. I’d like to use my existing error handling, using the failure crate.

One simple workaround is not to deserialize into your final structure, but a simpler one, and then post-process it.

selection could be an enum with either Vec<String> or String. Serde will know out of the box how to deserialize that much. And then parse the globs yourself, and copy them to the final struct.

Might this example be along the lines of what you’re looking for? They delegate deserialization of a field to a function that runs different logic depending on whether the value is a string of a struct - if you replaced their visit_map with a visit_seq, and added your GlobSet parsing into those visitor methods, that might get you where you’re wanting to go.

That said, I agree with @kornel that sometimes it’s wise to just use an intermediate structure if deserializing directly ends up being too complex :slight_smile: