# Path: pymatgen/db/vv/util.py
# class JsonWalker:
#     """Walk a dict, transforming.
#     Used for JSON formatting.
#     """
# 
#     def __init__(self, value_transform=None, dict_transform=None):
#         """Constructor.
# 
#         :param value_transform: Apply this function to each value in a list or dict.
#         :type value_transform: function taking a single arg (the value)
#         :param dict_transform: Apply this function to each dict
#         :type dict_transform: function taking a single arg (the dict)
#         """
#         self._vx = value_transform
#         self._dx = dict_transform
# 
#     def walk(self, o):
#         """Walk a dict & transform."""
#         if isinstance(o, dict):
#             d = o if self._dx is None else self._dx(o)
#             return {k: self.walk(v) for k, v in d.items()}
#         elif isinstance(o, list):
#             return [self.walk(v) for v in o]
#         else:
#             return o if self._vx is None else self._vx(o)
# 
#     @staticmethod
#     def value_json(o):
#         """Apply as_json() method on object to get value,
#         otherwise return object itself as the value.
#         """
#         if hasattr(o, "as_json"):
#             return o.as_json()
#         return o
# 
#     @staticmethod
#     def dict_expand(o):
#         """Expand keys in a dict with '.' in them into
#         sub-dictionaries, e.g.
# 
#         {'a.b.c': 'foo'} ==> {'a': {'b': {'c': 'foo'}}}
#         """
#         r = {}
#         for k, v in o.items():
#             if isinstance(k, str):
#                 k = k.replace("$", "_")
#             if "." in k:
#                 sub_r, keys = r, k.split(".")
#                 # create sub-dicts until last part of key
#                 for k2 in keys[:-1]:
#                     sub_r[k2] = {}
#                     sub_r = sub_r[k2]  # descend
#                     # assign last part of key to value
#                 sub_r[keys[-1]] = v
#             else:
#                 r[k] = v
#         return r
# 
# class YamlConfig(Action):
#     """Populate arguments with YAML file contents.
# 
#     Adapted from:
#       http://code.activestate.com/recipes/577918-filling-command-line-arguments-with-a-file/
#     """
# 
#     def __call__(self, parser, namespace, values, option_string=None):
#         config = self._get_config_from_file(values)
#         for key, value in config.items():
#             setattr(namespace, key, value)
#         _alog.debug(f"YamlConfig.namespace={namespace}")
# 
#     def _get_config_from_file(self, filename):
#         with open(filename) as f:
#             config = yaml.load(f)
#         return config


from argparse import ArgumentParser
from pymatgen.db.vv.util import JsonWalker, YamlConfig
import unittest


class Jsonable:
    def __init__(self, s):
        self.value = s

    def as_json(self):
        return f"{self.value}zinho"


class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.init_yaml()

    ## JsonWalker

    def test_json_walker(self):
        """JsonWalker class."""
        doc = {
            "hello": "world",
            "nested.value": 123,
            "funny$$char": [1, 2, 3],
            "listy": [{"item": Jsonable("Ciao")}],
        }
        expected = {
            "hello": "world",
            "nested": {"value": 123},
            "funny__char": [1, 2, 3],
            "listy": [{"item": "Ciaozinho"}],
        }

# Path: pymatgen/db/vv/util.py
# class JsonWalker:
#     """Walk a dict, transforming.
#     Used for JSON formatting.
#     """
# 
#     def __init__(self, value_transform=None, dict_transform=None):
#         """Constructor.
# 
#         :param value_transform: Apply this function to each value in a list or dict.
#         :type value_transform: function taking a single arg (the value)
#         :param dict_transform: Apply this function to each dict
#         :type dict_transform: function taking a single arg (the dict)
#         """
#         self._vx = value_transform
#         self._dx = dict_transform
# 
#     def walk(self, o):
#         """Walk a dict & transform."""
#         if isinstance(o, dict):
#             d = o if self._dx is None else self._dx(o)
#             return {k: self.walk(v) for k, v in d.items()}
#         elif isinstance(o, list):
#             return [self.walk(v) for v in o]
#         else:
#             return o if self._vx is None else self._vx(o)
# 
#     @staticmethod
#     def value_json(o):
#         """Apply as_json() method on object to get value,
#         otherwise return object itself as the value.
#         """
#         if hasattr(o, "as_json"):
#             return o.as_json()
#         return o
# 
#     @staticmethod
#     def dict_expand(o):
#         """Expand keys in a dict with '.' in them into
#         sub-dictionaries, e.g.
# 
#         {'a.b.c': 'foo'} ==> {'a': {'b': {'c': 'foo'}}}
#         """
#         r = {}
#         for k, v in o.items():
#             if isinstance(k, str):
#                 k = k.replace("$", "_")
#             if "." in k:
#                 sub_r, keys = r, k.split(".")
#                 # create sub-dicts until last part of key
#                 for k2 in keys[:-1]:
#                     sub_r[k2] = {}
#                     sub_r = sub_r[k2]  # descend
#                     # assign last part of key to value
#                 sub_r[keys[-1]] = v
#             else:
#                 r[k] = v
#         return r
# 
# class YamlConfig(Action):
#     """Populate arguments with YAML file contents.
# 
#     Adapted from:
#       http://code.activestate.com/recipes/577918-filling-command-line-arguments-with-a-file/
#     """
# 
#     def __call__(self, parser, namespace, values, option_string=None):
#         config = self._get_config_from_file(values)
#         for key, value in config.items():
#             setattr(namespace, key, value)
#         _alog.debug(f"YamlConfig.namespace={namespace}")
# 
#     def _get_config_from_file(self, filename):
#         with open(filename) as f:
#             config = yaml.load(f)
#         return config


# Path: pymatgen/db/vv/tests/test_util.py
from argparse import ArgumentParser
from pymatgen.db.vv.util import JsonWalker, YamlConfig
import unittest



class Jsonable:
    def __init__(self, s):
        self.value = s

    def as_json(self):
        return f"{self.value}zinho"


class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.init_yaml()

    ## JsonWalker

    def test_json_walker(self):
        """JsonWalker class."""
        doc = {
            "hello": "world",
            "nested.value": 123,
            "funny$$char": [1, 2, 3],
            "listy": [{"item": Jsonable("Ciao")}],
        }
        expected = {
            "hello": "world",
            "nested": {"value": 123},
            "funny__char": [1, 2, 3],
            "listy": [{"item": "Ciaozinho"}],
        }

        walker = JsonWalker(value_transform=JsonWalker.value_json, dict_transform=JsonWalker.dict_expand)