1from typing import Any, Dict, Optional, Union
2
3from tartiflette import Scalar
4from tartiflette.constants import UNDEFINED_VALUE
5from tartiflette.language.ast import StringValueNode
6
7
8class ScalarString:
9    """
10    Built-in scalar which handle string values.
11    """
12
13    def coerce_output(self, value: Any) -> str:
14        """
15        Coerce the resolved value for output.
16        :param value: value to coerce
17        :type value: Any
18        :return: the coerced value
19        :rtype: str
20        """
21        # pylint: disable=no-self-use
22        if isinstance(value, str):
23            return value
24
25        if isinstance(value, bool):
26            return "true" if value else "false"
27
28        try:
29            # TODO: maybe we shouldn't accepts None, list, dict, exceptions...
30            return str(value)
31        except Exception:  # pylint: disable=broad-except
32            pass
33        raise TypeError(f"String cannot represent value: < {value} >.")
34
35    def coerce_input(self, value: Any) -> str:
36        """
37        Coerce the user input from variable value.
38        :param value: value to coerce
39        :type value: Any
40        :return: the coerced value
41        :rtype: str
42        """
43        # pylint: disable=no-self-use
44        if not isinstance(value, str):
45            raise TypeError(
46                f"String cannot represent a non string value: < {value} >."
47            )
48        return value
49
50    def parse_literal(self, ast: "Node") -> Union[str, "UNDEFINED_VALUE"]:
51        """
52        Coerce the input value from an AST node.
53        :param ast: AST node to coerce
54        :type ast: Node
55        :return: the coerced value
56        :rtype: Union[str, UNDEFINED_VALUE]
57        """
58        # pylint: disable=no-self-use
59        return (
60            ast.value if isinstance(ast, StringValueNode) else UNDEFINED_VALUE
61        )
62
63
64def bake(schema_name: str, config: Optional[Dict[str, Any]] = None) -> str:
65    """
66    Links the scalar to the appropriate schema and returns the SDL related
67    to the scalar.
68    :param schema_name: schema name to link with
69    :param config: configuration of the scalar
70    :type schema_name: str
71    :type config: Optional[Dict[str, Any]]
72    :return: the SDL related to the scalar
73    :rtype: str
74    """
75    # pylint: disable=unused-argument
76    Scalar("String", schema_name=schema_name)(ScalarString())
77    return '''
78    """The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."""
79    scalar String
80    '''
81