{#
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-#}
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# DO NOT EDIT IT MANUALLY. This file is generated by opendal/dev/generate/python.rs.

"""Typed service configurations.

Each `*Config` is a `TypedDict` describing one OpenDAL service. The `scheme`
key is a `Literal` that binds the dict to its service, so a static type checker
rejects a wrong scheme, a missing required key, an unknown/misspelled key, and
a wrong value type.

Build a config with the call form or an annotated variable, then pass it to
`Operator.from_config` / `AsyncOperator.from_config`:

```python
from opendal import Operator
from opendal.config import S3Config

op = Operator.from_config(S3Config(scheme="s3", bucket="b"))

config: S3Config = {"scheme": "s3", "bucket": "b"}
op = Operator.from_config(config)
```

`ServiceConfig` is the discriminated union of every `*Config`; `from_config`
accepts it, so a single signature type-checks every service.
"""

from __future__ import annotations

import os
from typing import TYPE_CHECKING, Literal, TypedDict

if TYPE_CHECKING:
    from typing_extensions import NotRequired, Required

{% for name in srvs %}
class {{ service_to_pascal(name) }}Config(TypedDict):
    """Configuration for the `{{ snake_to_kebab_case(name) }}` service."""

    scheme: Required[Literal["{{ snake_to_kebab_case(name) }}"]]
    """The service scheme; fixed to `"{{ snake_to_kebab_case(name) }}"`."""
{%- for field in srvs[name].config %}
    {%- set base_type = make_config_field_type(field) %}
    {%- set doc = make_config_field_doc(field) %}
    {%- if config_field_is_required(field) %}
    {{ field.name }}: Required[{{ base_type }}]
    {%- else %}
    {{ field.name }}: NotRequired[{{ base_type }}]
    {%- endif %}
    {%- if doc %}
    """{{ doc }}"""
    {%- endif %}
{%- endfor %}

{% endfor %}
ServiceConfig = (
{%- for name in srvs %}
{% if loop.first %}    {{ service_to_pascal(name) }}Config{% else %}    | {{ service_to_pascal(name) }}Config{% endif %}
{%- endfor %}
)
"""Discriminated union of every service configuration, keyed on `scheme`."""

__all__ = [
    "ServiceConfig",
{%- for name in srvs %}
    "{{ service_to_pascal(name) }}Config",
{%- endfor %}
]
