go -yaml имеет довольно минимальный интерфейс, как это типично для пакетов Go. Поскольку минимальная возможная структура, к которой вы можете получить доступ (через интерфейс Marshaler
/ Unmarshaler
), равна yaml.Node
, с ней невозможно осуществить циклическое переключение без изменения самого go -yaml (точно так же, как ruamel является форк PyYAML).
Для правильного кругового отключения вам необходимо:
- Сохранение комментариев и пробелов. Это должно происходить на уровне лексера, внешнем уровне очень немногих реализаций YAML (я знаю, что libyaml - единственный, кто это делает, но вы не можете передать в него токены лексера, так что это в принципе бесполезно для этой цели)
- Сохранение скалярного представления. Это труднее всего сделать правильно, так как процитированные скаляры позволяют вам экранировать любой символ Юникода, и если у вас есть только результирующая строка, вы не можете знать исходное представление. Я думаю, что даже Руамель не может воспроизвести скалярное представление. Скалярное представление также включает в себя то, где разрывы строк находятся в сложенном скаляре, индикаторы сжатия и вдавливания, ни один из которых не отображается в go -yaml.
- Сохранение якорей и псевдонимов. go -yaml фактически позволяет вам получить доступ к этому с помощью
Node.Anchor
, однако вам нужно выяснить, какой из узлов был первым, у которого есть привязки, а какие - другими, которые изначально были псевдонимами. Это сложно, потому что… - Сохранение порядка ключей. YAML определяет, что порядок ключей в отображении не должен передавать информацию о содержимом. Как правило, отображения загружаются в хэш-карту, которая теряет эту информацию (как в случае с Go
map
). Однако Node
обеспечивает исходный порядок дочерних элементов, поэтому это можно сделать в go -yaml. - Сохранение верхнего и нижнего колонтитула документа. YAML допускает директивы перед документом (
%YAML
и %TAG
), а также позволяет документам заканчиваться несколькими строками ...
(и комментариями между ними). Эта информация недоступна для go -yaml.
Поскольку круговое отключение идет вразрез с YAML spe c, если интерпретируется строго (поскольку оно не позволяет деталям представления оказывать влияние на обработку) обычно она не является частью реализации YAML, и afaik ruamel - единственная реализация, которая пытается это сделать.
Поэтому ответ таков: Конечно, это можно сделать в Go, но вам нужно реализовать это самостоятельно, возможно, разветвив go -yaml. Поскольку синтаксический анализ YAML сам по себе очень сложен ( см. Здесь , ни одна из реализаций не делает его полностью правильным), правильная реализация циклического отключения YAML, охватывающая все крайние случаи, будет очень сложной для написания, и я настоятельно рекомендую против это.