""" Silique (https://www.silique.fr) Copyright (C) 2022-2026 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . """ from typing import Any, List, Optional from json import dumps from tiramisu import groups from tiramisu.error import PropertiesOptionError, ConfigError from rougail.error import ExtensionError from .i18n import _ from .__version__ import __version__ class RougailOutputJson: output_name = "json" def __init__( self, config: "Config", *, rougailconfig: "RougailConfig" = None, user_data_errors: Optional[list] = None, user_data_warnings: Optional[list] = None, true_config: "Config" = None, **kwargs, ) -> None: if rougailconfig is None: from rougail import RougailConfig rougailconfig = RougailConfig rougailconfig["step.output"] = self.output_name if rougailconfig["step.output"] != self.output_name: raise ExtensionError( _('the "step.output" is not set to "{0}"').format(self.output_name) ) self.rougailconfig = rougailconfig self.config = config if true_config: self.true_config = true_config else: self.true_config = config try: groups.namespace self.support_namespace = True except AttributeError: self.support_namespace = False if user_data_errors: self.errors = user_data_errors else: self.errors = [] if user_data_warnings: self.warnings = user_data_warnings else: self.warnings = [] def run(self) -> None: ret = self.exporter() if isinstance(self.dico, str): value = self.dico else: value = dumps(self.dico, ensure_ascii=False, indent=2) return ret, value def print(self) -> str: ret, data = self.run() print(data) return ret def exporter(self) -> None: self.dico = {} self.manage_warnings() if not self.manage_errors(): return False if not self.config.isoptiondescription(): self.dico = self.config.value.get() return True self.parse_family( self.config, self.dico, None, ) return self.manage_errors() def manage_warnings(self) -> None: if not self.warnings: return warnings = [] for w in self.warnings: if isinstance(w, dict): msg, opt = next(iter(w.items())) warnings.append(_("{0}: {1}").format(opt.path, msg)) else: warnings.append(w) self.dico["_warnings"] = warnings def manage_errors(self) -> bool: if not self.errors: return True errors = [] for e in self.errors: if isinstance(e, dict): msg, opt = next(iter(e.items())) errors.append(_("{0}: {1}").format(opt.path, msg)) else: errors.append(e) self.dico["_errors"] = errors # self.manage_warnings() return False def parse_family( self, parent, parent_obj, namespace, ): for child in parent: if child.isoptiondescription(): if child.isleadership(): child_obj = [] self.parse_sequence( child, child_obj, ) else: if ( namespace is None and self.support_namespace and child.group_type() is groups.namespace ): subnamespace = child.name() else: subnamespace = namespace child_obj = self.get_default_family(child) self.parse_family(child, child_obj, subnamespace) self.family_informations(parent, parent_obj, child, child_obj) else: self.variable_informations(parent_obj, child) def parse_sequence( self, child, obj, ): leader, *followers = list(child) leader_values = leader.value.get() for idx, leader_value in enumerate(leader_values): leader_dict = {leader.name(): leader_value} obj.append(leader_dict) for follower in list(followers): if follower.index() != idx: continue followers.remove(follower) leader_dict[follower.name()] = follower.value.get() def get_default_family(self, child): return dict() def family_informations(self, parent, parent_obj, child, child_obj): parent_obj[child.name()] = child_obj def variable_informations(self, parent_obj, child): parent_obj[child.name()] = child.value.get() RougailOutput = RougailOutputJson __all__ = ("RougailOutputJson",)