FileParse supports serializing enums as human-readable strings using custom converter functions.
#include <fileParse/Enum.hxx>
#include <fileParse/Vector.hxx> // For enum vectors
#include <fileParse/Map.hxx> // For enum map keys
#include <fileParse/Common.hxx>
#include <fileParse/StringConversion.hxx>
#include <fileParse/FileDataHandler.hxx>enum class Priority {
Low,
Medium,
High,
Critical
};
// String array for conversion (must match enum order)
const std::array<std::string, 4> PriorityStrings = {
"Low", "Medium", "High", "Critical"
};
// Enum to string converter
std::string priorityToString(Priority p) {
return FileParse::enumToString(p, PriorityStrings);
}
// String to enum converter
Priority stringToPriority(std::string_view s) {
return FileParse::enumFromString(s, PriorityStrings, Priority::Low);
}struct Task {
std::string name;
Priority priority;
};template<typename NodeAdapter>
NodeAdapter& operator<<(NodeAdapter& node, const Task& t) {
node << FileParse::Child{"Name", t.name};
FileParse::serializeEnum(node, t.priority, priorityToString);
return node;
}
template<typename NodeAdapter>
const NodeAdapter& operator>>(const NodeAdapter& node, Task& t) {
node >> FileParse::Child{"Name", t.name};
FileParse::deserializeEnum(node, t.priority, stringToPriority);
return node;
}<Task>
<Name>Fix bug</Name>
High
</Task>To wrap the enum in its own node:
template<typename NodeAdapter>
NodeAdapter& operator<<(NodeAdapter& node, const Task& t) {
node << FileParse::Child{"Name", t.name};
auto priorityNode = node.addChild("Priority");
FileParse::serializeEnum(priorityNode, t.priority, priorityToString);
return node;
}
template<typename NodeAdapter>
const NodeAdapter& operator>>(const NodeAdapter& node, Task& t) {
node >> FileParse::Child{"Name", t.name};
if (auto priorityNode = node.getFirstChildByName("Priority"); priorityNode.has_value()) {
FileParse::deserializeEnum(priorityNode.value(), t.priority, stringToPriority);
}
return node;
}<Task>
<Name>Fix bug</Name>
<Priority>High</Priority>
</Task>struct TaskList {
std::vector<Priority> priorities;
};
template<typename NodeAdapter>
NodeAdapter& operator<<(NodeAdapter& node, const TaskList& t) {
FileParse::serializeEnumVector(node, {"Priorities", "Priority"}, t.priorities, priorityToString);
return node;
}
template<typename NodeAdapter>
const NodeAdapter& operator>>(const NodeAdapter& node, TaskList& t) {
FileParse::deserializeEnumVector(node, {"Priorities", "Priority"}, t.priorities, stringToPriority);
return node;
}<TaskList>
<Priorities>
<Priority>High</Priority>
<Priority>Low</Priority>
<Priority>Critical</Priority>
</Priorities>
</TaskList>struct PriorityLabels {
std::map<Priority, std::string> labels;
};
template<typename NodeAdapter>
NodeAdapter& operator<<(NodeAdapter& node, const PriorityLabels& p) {
FileParse::serializeEnumMap<NodeAdapter, Priority, std::string>(
node, p.labels, priorityToString);
return node;
}
template<typename NodeAdapter>
const NodeAdapter& operator>>(const NodeAdapter& node, PriorityLabels& p) {
FileParse::deserializeEnumMap<NodeAdapter, Priority, std::string>(
node, p.labels, stringToPriority);
return node;
}<PriorityLabels>
<Low>Not urgent</Low>
<High>Needs attention</High>
<Critical>Emergency</Critical>
</PriorityLabels>For more forgiving input parsing:
Priority stringToPriorityCaseInsensitive(std::string_view s) {
return FileParse::enumFromStringCaseInsensitive(s, PriorityStrings, Priority::Low);
}This allows "high", "HIGH", or "High" to all parse as Priority::High.
Alternative approach using a map:
const std::map<Priority, std::string> PriorityMap = {
{Priority::Low, "Low"},
{Priority::Medium, "Medium"},
{Priority::High, "High"},
{Priority::Critical, "Critical"}
};
std::string priorityToString(Priority p) {
return FileParse::enumToString(p, PriorityMap);
}
Priority stringToPriority(std::string_view s) {
return FileParse::enumFromString(s, PriorityMap, Priority::Low);
}- The string array/map must contain entries for all enum values
- A default value is returned when parsing unknown strings
- Enum values are always serialized as strings, not integers
- Both XML and JSON use the same string representation