def _validate_defn()

in msticpy/config/mp_config_control.py [0:0]


def _validate_defn(value, path, val_type, val_opts):
    """
    Validate a compound type definition.

    We want to validate a value against a definition like:
    ::
        cred_key:
            one_of:
                - str: str()
                - EnvironmentVar: str()
                - KeyVault: str(required=False)

    This only handles this type of definition and only looks at
    the "required" flag in the options. We'll extend this checker if we
    need to for other options.

    """
    mssg = _get_mssg(value, path)
    if _is_none_and_not_required(value, val_type, val_opts):
        return ValidtnResult(True, f"{_VALID_SUCESS} {mssg}")

    # This only handles "one_of" lists of alternatives
    opt_list = val_opts.get("defn", {}).get("one_of")
    if not opt_list:
        return ValidtnResult(True, f"{_VALID_SUCESS} {mssg}")
    # pull the definitions (val_type and val_opts) for each item into a dict
    opt_dict = {next(iter(val.keys())): next(iter(val.values())) for val in opt_list}

    # if the checked value is a string, validate the string
    if isinstance(value, str) and "str" in opt_dict:
        opt_v_opts = {"required": "required=False" not in opt_dict["str"]}
        return _validate_string(value, path, "str", opt_v_opts)

    # If the value is a dict
    if isinstance(value, dict):
        # We assume that the value is a dict with a single key
        v_key, v_val = next(iter(value.items()))
        # If the name is in the one_of dictionary names
        if v_key in opt_dict:
            # get the element type
            opt_v_type = re.sub(r"\(.*\)", "", opt_dict[v_key])
            # add "required=False" if that is the value options for this item
            opt_v_opts = {"required": "required=False" not in opt_dict[v_key]}
            # get the validator function for the option type and use that
            # to check the actual value
            _validator = _VALIDATORS.get(opt_v_type, _validate_string)
            return _validator(v_val, f"{path}.{v_key}", opt_v_type, opt_v_opts)
    # Otherwise the validation failed
    return ValidtnResult(
        False,
        f"Value type {type(value)} does not match definition {val_opts['defn']} - {mssg}",
    )