We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
msgspec output uses regex instead of pattern to Meta constraint
Strings with a pattern constraint are output as `Meta(regex='....')` however they should be output as `Meta(pattern='...')`

**To Reproduce**

Example schema:
```yaml
openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
components:
  schemas:
    info:
      type: object
      properties:
        hostName:
          type: string
          format: hostname
        arn:
          type: string
          pattern: '(^arn:([^:]*):([^:]*):([^:]*):(|\*|[\d]{12}):(.+)$)|^\*$'
```

Used commandline:
```bash
$ datamodel-codegen --input pattern.yaml --output output_file.py --input-file-type 'openapi' \
                --target-python '3.9' \
                --output-model-type msgspec.Struct
```

**Expected behavior**
The regex argument to the Meta annotation should be `pattern`

```python
class Info(Struct):
    hostName: Optional[str] = None
    arn: Optional[
        Annotated[
            str,
            Meta(pattern='(^arn:([^:]*):([^:]*):([^:]*):(|\\*|[\\d]{12}):(.+)$)|^\\*$'),
        ]
    ] = None
```

**Version:**
 - OS: macOS
 - Python version: 3.11.4
 - datamodel-code-generator version: 0.22


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `datamodel_code_generator/model/msgspec.py`
Content:
```
1 from pathlib import Path
2 from typing import Any, ClassVar, DefaultDict, Dict, List, Optional, Set, Tuple
3 
4 from datamodel_code_generator.imports import Import
5 from datamodel_code_generator.model import DataModel, DataModelFieldBase
6 from datamodel_code_generator.model.base import UNDEFINED
7 from datamodel_code_generator.model.imports import (
8     IMPORT_MSGSPEC_CONVERT,
9     IMPORT_MSGSPEC_FIELD,
10     IMPORT_MSGSPEC_META,
11     IMPORT_MSGSPEC_STRUCT,
12 )
13 from datamodel_code_generator.model.pydantic.base_model import Constraints
14 from datamodel_code_generator.model.rootmodel import RootModel
15 from datamodel_code_generator.reference import Reference
16 from datamodel_code_generator.types import chain_as_tuple
17 
18 
19 def _has_field_assignment(field: DataModelFieldBase) -> bool:
20     return bool(field.field) or not (
21         field.required
22         or (field.represented_default == 'None' and field.strip_default_none)
23     )
24 
25 
26 class Struct(DataModel):
27     TEMPLATE_FILE_PATH: ClassVar[str] = 'msgspec.jinja2'
28     BASE_CLASS: ClassVar[str] = 'msgspec.Struct'
29     DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = (IMPORT_MSGSPEC_STRUCT,)
30 
31     def __init__(
32         self,
33         *,
34         reference: Reference,
35         fields: List[DataModelFieldBase],
36         decorators: Optional[List[str]] = None,
37         base_classes: Optional[List[Reference]] = None,
38         custom_base_class: Optional[str] = None,
39         custom_template_dir: Optional[Path] = None,
40         extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
41         methods: Optional[List[str]] = None,
42         path: Optional[Path] = None,
43         description: Optional[str] = None,
44         default: Any = UNDEFINED,
45         nullable: bool = False,
46     ) -> None:
47         super().__init__(
48             reference=reference,
49             fields=sorted(fields, key=_has_field_assignment, reverse=False),
50             decorators=decorators,
51             base_classes=base_classes,
52             custom_base_class=custom_base_class,
53             custom_template_dir=custom_template_dir,
54             extra_template_data=extra_template_data,
55             methods=methods,
56             path=path,
57             description=description,
58             default=default,
59             nullable=nullable,
60         )
61 
62     @property
63     def imports(self) -> Tuple[Import, ...]:
64         extra_imports = []
65         if any(f for f in self.fields if f.field):
66             extra_imports.append(IMPORT_MSGSPEC_FIELD)
67         if any(f for f in self.fields if f.field and 'lambda: convert' in f.field):
68             extra_imports.append(IMPORT_MSGSPEC_CONVERT)
69         if any(f for f in self.fields if f.annotated):
70             extra_imports.append(IMPORT_MSGSPEC_META)
71         return chain_as_tuple(super().imports, extra_imports)
72 
73 
74 class DataModelField(DataModelFieldBase):
75     _FIELD_KEYS: ClassVar[Set[str]] = {
76         'default',
77         'default_factory',
78     }
79     _META_FIELD_KEYS: ClassVar[Set[str]] = {
80         'title',
81         'description',
82         'gt',
83         'ge',
84         'lt',
85         'le',
86         'multiple_of',
87         # 'min_items', # not supported by msgspec
88         # 'max_items', # not supported by msgspec
89         'min_length',
90         'max_length',
91         'regex',
92         # 'unique_items', # not supported by msgspec
93     }
94     _PARSE_METHOD = 'convert'
95     _COMPARE_EXPRESSIONS: ClassVar[Set[str]] = {'gt', 'ge', 'lt', 'le', 'multiple_of'}
96     constraints: Optional[Constraints] = None
97 
98     def self_reference(self) -> bool:  # pragma: no cover
99         return isinstance(self.parent, Struct) and self.parent.reference.path in {
100             d.reference.path for d in self.data_type.all_data_types if d.reference
101         }
102 
103     def process_const(self) -> None:
104         if 'const' not in self.extras:
105             return None
106         self.const = True
107         self.nullable = False
108         const = self.extras['const']
109         if self.data_type.type == 'str' and isinstance(
110             const, str
111         ):  # pragma: no cover # Literal supports only str
112             self.data_type = self.data_type.__class__(literals=[const])
113 
114     def _get_strict_field_constraint_value(self, constraint: str, value: Any) -> Any:
115         if value is None or constraint not in self._COMPARE_EXPRESSIONS:
116             return value
117 
118         if any(
119             data_type.type == 'float' for data_type in self.data_type.all_data_types
120         ):
121             return float(value)
122         return int(value)
123 
124     @property
125     def field(self) -> Optional[str]:
126         """for backwards compatibility"""
127         result = str(self)
128         if result == '':
129             return None
130 
131         return result
132 
133     def __str__(self) -> str:
134         data: Dict[str, Any] = {
135             k: v for k, v in self.extras.items() if k in self._FIELD_KEYS
136         }
137         if self.alias:
138             data['name'] = self.alias
139 
140         if self.default != UNDEFINED and self.default is not None:
141             data['default'] = self.default
142 
143         if self.required:
144             data = {
145                 k: v
146                 for k, v in data.items()
147                 if k
148                 not in (
149                     'default',
150                     'default_factory',
151                 )
152             }
153         elif self.default and 'default_factory' not in data:
154             default_factory = self._get_default_as_struct_model()
155             if default_factory is not None:
156                 data.pop('default')
157                 data['default_factory'] = default_factory
158 
159         if not data:
160             return ''
161 
162         if len(data) == 1 and 'default' in data:
163             return repr(data['default'])
164 
165         kwargs = [
166             f'{k}={v if k == "default_factory" else repr(v)}' for k, v in data.items()
167         ]
168         return f'field({", ".join(kwargs)})'
169 
170     @property
171     def annotated(self) -> Optional[str]:
172         if not self.use_annotated:  # pragma: no cover
173             return None
174 
175         data: Dict[str, Any] = {
176             k: v for k, v in self.extras.items() if k in self._META_FIELD_KEYS
177         }
178         if (
179             self.constraints is not None
180             and not self.self_reference()
181             and not self.data_type.strict
182         ):
183             data = {
184                 **data,
185                 **{
186                     k: self._get_strict_field_constraint_value(k, v)
187                     for k, v in self.constraints.dict().items()
188                     if k in self._META_FIELD_KEYS
189                 },
190             }
191 
192         meta_arguments = sorted(
193             f'{k}={repr(v)}' for k, v in data.items() if v is not None
194         )
195         if not meta_arguments:
196             return None
197 
198         meta = f'Meta({", ".join(meta_arguments)})'
199 
200         return f'Annotated[{self.type_hint}, {meta}]'
201 
202     def _get_default_as_struct_model(self) -> Optional[str]:
203         for data_type in self.data_type.data_types or (self.data_type,):
204             # TODO: Check nested data_types
205             if data_type.is_dict or self.data_type.is_union:
206                 # TODO: Parse Union and dict model for default
207                 continue  # pragma: no cover
208             elif data_type.is_list and len(data_type.data_types) == 1:
209                 data_type = data_type.data_types[0]
210                 if (  # pragma: no cover
211                     data_type.reference
212                     and (
213                         isinstance(data_type.reference.source, Struct)
214                         or isinstance(data_type.reference.source, RootModel)
215                     )
216                     and isinstance(self.default, list)
217                 ):
218                     return f'lambda: {self._PARSE_METHOD}({repr(self.default)},  type=list[{data_type.alias or data_type.reference.source.class_name}])'
219             elif data_type.reference and isinstance(data_type.reference.source, Struct):
220                 return f'lambda: {self._PARSE_METHOD}({repr(self.default)},  type={data_type.alias or data_type.reference.source.class_name})'
221         return None
222
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/datamodel_code_generator/model/msgspec.py b/datamodel_code_generator/model/msgspec.py
--- a/datamodel_code_generator/model/msgspec.py
+++ b/datamodel_code_generator/model/msgspec.py
@@ -1,6 +1,8 @@
 from pathlib import Path
 from typing import Any, ClassVar, DefaultDict, Dict, List, Optional, Set, Tuple
 
+from pydantic import Field
+
 from datamodel_code_generator.imports import Import
 from datamodel_code_generator.model import DataModel, DataModelFieldBase
 from datamodel_code_generator.model.base import UNDEFINED
@@ -10,10 +12,12 @@
     IMPORT_MSGSPEC_META,
     IMPORT_MSGSPEC_STRUCT,
 )
-from datamodel_code_generator.model.pydantic.base_model import Constraints
+from datamodel_code_generator.model.pydantic.base_model import (
+    Constraints as _Constraints,
+)
 from datamodel_code_generator.model.rootmodel import RootModel
 from datamodel_code_generator.reference import Reference
-from datamodel_code_generator.types import chain_as_tuple
+from datamodel_code_generator.types import chain_as_tuple, get_optional_type
 
 
 def _has_field_assignment(field: DataModelFieldBase) -> bool:
@@ -71,6 +75,12 @@
         return chain_as_tuple(super().imports, extra_imports)
 
 
+class Constraints(_Constraints):
+    # To override existing pattern alias
+    regex: Optional[str] = Field(None, alias='regex')
+    pattern: Optional[str] = Field(None, alias='pattern')
+
+
 class DataModelField(DataModelFieldBase):
     _FIELD_KEYS: ClassVar[Set[str]] = {
         'default',
@@ -88,7 +98,7 @@
         # 'max_items', # not supported by msgspec
         'min_length',
         'max_length',
-        'regex',
+        'pattern',
         # 'unique_items', # not supported by msgspec
     }
     _PARSE_METHOD = 'convert'
@@ -197,6 +207,10 @@
 
         meta = f'Meta({", ".join(meta_arguments)})'
 
+        if not self.required:
+            type_hint = self.data_type.type_hint
+            annotated_type = f'Annotated[{type_hint}, {meta}]'
+            return get_optional_type(annotated_type, self.data_type.use_union_operator)
         return f'Annotated[{self.type_hint}, {meta}]'
 
     def _get_default_as_struct_model(self) -> Optional[str]:

{"golden_diff": "diff --git a/datamodel_code_generator/model/msgspec.py b/datamodel_code_generator/model/msgspec.py\n--- a/datamodel_code_generator/model/msgspec.py\n+++ b/datamodel_code_generator/model/msgspec.py\n@@ -1,6 +1,8 @@\n from pathlib import Path\n from typing import Any, ClassVar, DefaultDict, Dict, List, Optional, Set, Tuple\n \n+from pydantic import Field\n+\n from datamodel_code_generator.imports import Import\n from datamodel_code_generator.model import DataModel, DataModelFieldBase\n from datamodel_code_generator.model.base import UNDEFINED\n@@ -10,10 +12,12 @@\n     IMPORT_MSGSPEC_META,\n     IMPORT_MSGSPEC_STRUCT,\n )\n-from datamodel_code_generator.model.pydantic.base_model import Constraints\n+from datamodel_code_generator.model.pydantic.base_model import (\n+    Constraints as _Constraints,\n+)\n from datamodel_code_generator.model.rootmodel import RootModel\n from datamodel_code_generator.reference import Reference\n-from datamodel_code_generator.types import chain_as_tuple\n+from datamodel_code_generator.types import chain_as_tuple, get_optional_type\n \n \n def _has_field_assignment(field: DataModelFieldBase) -> bool:\n@@ -71,6 +75,12 @@\n         return chain_as_tuple(super().imports, extra_imports)\n \n \n+class Constraints(_Constraints):\n+    # To override existing pattern alias\n+    regex: Optional[str] = Field(None, alias='regex')\n+    pattern: Optional[str] = Field(None, alias='pattern')\n+\n+\n class DataModelField(DataModelFieldBase):\n     _FIELD_KEYS: ClassVar[Set[str]] = {\n         'default',\n@@ -88,7 +98,7 @@\n         # 'max_items', # not supported by msgspec\n         'min_length',\n         'max_length',\n-        'regex',\n+        'pattern',\n         # 'unique_items', # not supported by msgspec\n     }\n     _PARSE_METHOD = 'convert'\n@@ -197,6 +207,10 @@\n \n         meta = f'Meta({\", \".join(meta_arguments)})'\n \n+        if not self.required:\n+            type_hint = self.data_type.type_hint\n+            annotated_type = f'Annotated[{type_hint}, {meta}]'\n+            return get_optional_type(annotated_type, self.data_type.use_union_operator)\n         return f'Annotated[{self.type_hint}, {meta}]'\n \n     def _get_default_as_struct_model(self) -> Optional[str]:\n", "issue": "msgspec output uses regex instead of pattern to Meta constraint\nStrings with a pattern constraint are output as `Meta(regex='....')` however they should be output as `Meta(pattern='...')`\r\n\r\n**To Reproduce**\r\n\r\nExample schema:\r\n```yaml\r\nopenapi: \"3.0.0\"\r\ninfo:\r\n  version: 1.0.0\r\n  title: Swagger Petstore\r\n  license:\r\n    name: MIT\r\nservers:\r\n  - url: http://petstore.swagger.io/v1\r\ncomponents:\r\n  schemas:\r\n    info:\r\n      type: object\r\n      properties:\r\n        hostName:\r\n          type: string\r\n          format: hostname\r\n        arn:\r\n          type: string\r\n          pattern: '(^arn:([^:]*):([^:]*):([^:]*):(|\\*|[\\d]{12}):(.+)$)|^\\*$'\r\n```\r\n\r\nUsed commandline:\r\n```bash\r\n$ datamodel-codegen --input pattern.yaml --output output_file.py --input-file-type 'openapi' \\\r\n                --target-python '3.9' \\\r\n                --output-model-type msgspec.Struct\r\n```\r\n\r\n**Expected behavior**\r\nThe regex argument to the Meta annotation should be `pattern`\r\n\r\n```python\r\nclass Info(Struct):\r\n    hostName: Optional[str] = None\r\n    arn: Optional[\r\n        Annotated[\r\n            str,\r\n            Meta(pattern='(^arn:([^:]*):([^:]*):([^:]*):(|\\\\*|[\\\\d]{12}):(.+)$)|^\\\\*$'),\r\n        ]\r\n    ] = None\r\n```\r\n\r\n**Version:**\r\n - OS: macOS\r\n - Python version: 3.11.4\r\n - datamodel-code-generator version: 0.22\r\n\n", "before_files": [{"content": "from pathlib import Path\nfrom typing import Any, ClassVar, DefaultDict, Dict, List, Optional, Set, Tuple\n\nfrom datamodel_code_generator.imports import Import\nfrom datamodel_code_generator.model import DataModel, DataModelFieldBase\nfrom datamodel_code_generator.model.base import UNDEFINED\nfrom datamodel_code_generator.model.imports import (\n    IMPORT_MSGSPEC_CONVERT,\n    IMPORT_MSGSPEC_FIELD,\n    IMPORT_MSGSPEC_META,\n    IMPORT_MSGSPEC_STRUCT,\n)\nfrom datamodel_code_generator.model.pydantic.base_model import Constraints\nfrom datamodel_code_generator.model.rootmodel import RootModel\nfrom datamodel_code_generator.reference import Reference\nfrom datamodel_code_generator.types import chain_as_tuple\n\n\ndef _has_field_assignment(field: DataModelFieldBase) -> bool:\n    return bool(field.field) or not (\n        field.required\n        or (field.represented_default == 'None' and field.strip_default_none)\n    )\n\n\nclass Struct(DataModel):\n    TEMPLATE_FILE_PATH: ClassVar[str] = 'msgspec.jinja2'\n    BASE_CLASS: ClassVar[str] = 'msgspec.Struct'\n    DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = (IMPORT_MSGSPEC_STRUCT,)\n\n    def __init__(\n        self,\n        *,\n        reference: Reference,\n        fields: List[DataModelFieldBase],\n        decorators: Optional[List[str]] = None,\n        base_classes: Optional[List[Reference]] = None,\n        custom_base_class: Optional[str] = None,\n        custom_template_dir: Optional[Path] = None,\n        extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,\n        methods: Optional[List[str]] = None,\n        path: Optional[Path] = None,\n        description: Optional[str] = None,\n        default: Any = UNDEFINED,\n        nullable: bool = False,\n    ) -> None:\n        super().__init__(\n            reference=reference,\n            fields=sorted(fields, key=_has_field_assignment, reverse=False),\n            decorators=decorators,\n            base_classes=base_classes,\n            custom_base_class=custom_base_class,\n            custom_template_dir=custom_template_dir,\n            extra_template_data=extra_template_data,\n            methods=methods,\n            path=path,\n            description=description,\n            default=default,\n            nullable=nullable,\n        )\n\n    @property\n    def imports(self) -> Tuple[Import, ...]:\n        extra_imports = []\n        if any(f for f in self.fields if f.field):\n            extra_imports.append(IMPORT_MSGSPEC_FIELD)\n        if any(f for f in self.fields if f.field and 'lambda: convert' in f.field):\n            extra_imports.append(IMPORT_MSGSPEC_CONVERT)\n        if any(f for f in self.fields if f.annotated):\n            extra_imports.append(IMPORT_MSGSPEC_META)\n        return chain_as_tuple(super().imports, extra_imports)\n\n\nclass DataModelField(DataModelFieldBase):\n    _FIELD_KEYS: ClassVar[Set[str]] = {\n        'default',\n        'default_factory',\n    }\n    _META_FIELD_KEYS: ClassVar[Set[str]] = {\n        'title',\n        'description',\n        'gt',\n        'ge',\n        'lt',\n        'le',\n        'multiple_of',\n        # 'min_items', # not supported by msgspec\n        # 'max_items', # not supported by msgspec\n        'min_length',\n        'max_length',\n        'regex',\n        # 'unique_items', # not supported by msgspec\n    }\n    _PARSE_METHOD = 'convert'\n    _COMPARE_EXPRESSIONS: ClassVar[Set[str]] = {'gt', 'ge', 'lt', 'le', 'multiple_of'}\n    constraints: Optional[Constraints] = None\n\n    def self_reference(self) -> bool:  # pragma: no cover\n        return isinstance(self.parent, Struct) and self.parent.reference.path in {\n            d.reference.path for d in self.data_type.all_data_types if d.reference\n        }\n\n    def process_const(self) -> None:\n        if 'const' not in self.extras:\n            return None\n        self.const = True\n        self.nullable = False\n        const = self.extras['const']\n        if self.data_type.type == 'str' and isinstance(\n            const, str\n        ):  # pragma: no cover # Literal supports only str\n            self.data_type = self.data_type.__class__(literals=[const])\n\n    def _get_strict_field_constraint_value(self, constraint: str, value: Any) -> Any:\n        if value is None or constraint not in self._COMPARE_EXPRESSIONS:\n            return value\n\n        if any(\n            data_type.type == 'float' for data_type in self.data_type.all_data_types\n        ):\n            return float(value)\n        return int(value)\n\n    @property\n    def field(self) -> Optional[str]:\n        \"\"\"for backwards compatibility\"\"\"\n        result = str(self)\n        if result == '':\n            return None\n\n        return result\n\n    def __str__(self) -> str:\n        data: Dict[str, Any] = {\n            k: v for k, v in self.extras.items() if k in self._FIELD_KEYS\n        }\n        if self.alias:\n            data['name'] = self.alias\n\n        if self.default != UNDEFINED and self.default is not None:\n            data['default'] = self.default\n\n        if self.required:\n            data = {\n                k: v\n                for k, v in data.items()\n                if k\n                not in (\n                    'default',\n                    'default_factory',\n                )\n            }\n        elif self.default and 'default_factory' not in data:\n            default_factory = self._get_default_as_struct_model()\n            if default_factory is not None:\n                data.pop('default')\n                data['default_factory'] = default_factory\n\n        if not data:\n            return ''\n\n        if len(data) == 1 and 'default' in data:\n            return repr(data['default'])\n\n        kwargs = [\n            f'{k}={v if k == \"default_factory\" else repr(v)}' for k, v in data.items()\n        ]\n        return f'field({\", \".join(kwargs)})'\n\n    @property\n    def annotated(self) -> Optional[str]:\n        if not self.use_annotated:  # pragma: no cover\n            return None\n\n        data: Dict[str, Any] = {\n            k: v for k, v in self.extras.items() if k in self._META_FIELD_KEYS\n        }\n        if (\n            self.constraints is not None\n            and not self.self_reference()\n            and not self.data_type.strict\n        ):\n            data = {\n                **data,\n                **{\n                    k: self._get_strict_field_constraint_value(k, v)\n                    for k, v in self.constraints.dict().items()\n                    if k in self._META_FIELD_KEYS\n                },\n            }\n\n        meta_arguments = sorted(\n            f'{k}={repr(v)}' for k, v in data.items() if v is not None\n        )\n        if not meta_arguments:\n            return None\n\n        meta = f'Meta({\", \".join(meta_arguments)})'\n\n        return f'Annotated[{self.type_hint}, {meta}]'\n\n    def _get_default_as_struct_model(self) -> Optional[str]:\n        for data_type in self.data_type.data_types or (self.data_type,):\n            # TODO: Check nested data_types\n            if data_type.is_dict or self.data_type.is_union:\n                # TODO: Parse Union and dict model for default\n                continue  # pragma: no cover\n            elif data_type.is_list and len(data_type.data_types) == 1:\n                data_type = data_type.data_types[0]\n                if (  # pragma: no cover\n                    data_type.reference\n                    and (\n                        isinstance(data_type.reference.source, Struct)\n                        or isinstance(data_type.reference.source, RootModel)\n                    )\n                    and isinstance(self.default, list)\n                ):\n                    return f'lambda: {self._PARSE_METHOD}({repr(self.default)},  type=list[{data_type.alias or data_type.reference.source.class_name}])'\n            elif data_type.reference and isinstance(data_type.reference.source, Struct):\n                return f'lambda: {self._PARSE_METHOD}({repr(self.default)},  type={data_type.alias or data_type.reference.source.class_name})'\n        return None\n", "path": "datamodel_code_generator/model/msgspec.py"}], "after_files": [{"content": "from pathlib import Path\nfrom typing import Any, ClassVar, DefaultDict, Dict, List, Optional, Set, Tuple\n\nfrom pydantic import Field\n\nfrom datamodel_code_generator.imports import Import\nfrom datamodel_code_generator.model import DataModel, DataModelFieldBase\nfrom datamodel_code_generator.model.base import UNDEFINED\nfrom datamodel_code_generator.model.imports import (\n    IMPORT_MSGSPEC_CONVERT,\n    IMPORT_MSGSPEC_FIELD,\n    IMPORT_MSGSPEC_META,\n    IMPORT_MSGSPEC_STRUCT,\n)\nfrom datamodel_code_generator.model.pydantic.base_model import (\n    Constraints as _Constraints,\n)\nfrom datamodel_code_generator.model.rootmodel import RootModel\nfrom datamodel_code_generator.reference import Reference\nfrom datamodel_code_generator.types import chain_as_tuple, get_optional_type\n\n\ndef _has_field_assignment(field: DataModelFieldBase) -> bool:\n    return bool(field.field) or not (\n        field.required\n        or (field.represented_default == 'None' and field.strip_default_none)\n    )\n\n\nclass Struct(DataModel):\n    TEMPLATE_FILE_PATH: ClassVar[str] = 'msgspec.jinja2'\n    BASE_CLASS: ClassVar[str] = 'msgspec.Struct'\n    DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = (IMPORT_MSGSPEC_STRUCT,)\n\n    def __init__(\n        self,\n        *,\n        reference: Reference,\n        fields: List[DataModelFieldBase],\n        decorators: Optional[List[str]] = None,\n        base_classes: Optional[List[Reference]] = None,\n        custom_base_class: Optional[str] = None,\n        custom_template_dir: Optional[Path] = None,\n        extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,\n        methods: Optional[List[str]] = None,\n        path: Optional[Path] = None,\n        description: Optional[str] = None,\n        default: Any = UNDEFINED,\n        nullable: bool = False,\n    ) -> None:\n        super().__init__(\n            reference=reference,\n            fields=sorted(fields, key=_has_field_assignment, reverse=False),\n            decorators=decorators,\n            base_classes=base_classes,\n            custom_base_class=custom_base_class,\n            custom_template_dir=custom_template_dir,\n            extra_template_data=extra_template_data,\n            methods=methods,\n            path=path,\n            description=description,\n            default=default,\n            nullable=nullable,\n        )\n\n    @property\n    def imports(self) -> Tuple[Import, ...]:\n        extra_imports = []\n        if any(f for f in self.fields if f.field):\n            extra_imports.append(IMPORT_MSGSPEC_FIELD)\n        if any(f for f in self.fields if f.field and 'lambda: convert' in f.field):\n            extra_imports.append(IMPORT_MSGSPEC_CONVERT)\n        if any(f for f in self.fields if f.annotated):\n            extra_imports.append(IMPORT_MSGSPEC_META)\n        return chain_as_tuple(super().imports, extra_imports)\n\n\nclass Constraints(_Constraints):\n    # To override existing pattern alias\n    regex: Optional[str] = Field(None, alias='regex')\n    pattern: Optional[str] = Field(None, alias='pattern')\n\n\nclass DataModelField(DataModelFieldBase):\n    _FIELD_KEYS: ClassVar[Set[str]] = {\n        'default',\n        'default_factory',\n    }\n    _META_FIELD_KEYS: ClassVar[Set[str]] = {\n        'title',\n        'description',\n        'gt',\n        'ge',\n        'lt',\n        'le',\n        'multiple_of',\n        # 'min_items', # not supported by msgspec\n        # 'max_items', # not supported by msgspec\n        'min_length',\n        'max_length',\n        'pattern',\n        # 'unique_items', # not supported by msgspec\n    }\n    _PARSE_METHOD = 'convert'\n    _COMPARE_EXPRESSIONS: ClassVar[Set[str]] = {'gt', 'ge', 'lt', 'le', 'multiple_of'}\n    constraints: Optional[Constraints] = None\n\n    def self_reference(self) -> bool:  # pragma: no cover\n        return isinstance(self.parent, Struct) and self.parent.reference.path in {\n            d.reference.path for d in self.data_type.all_data_types if d.reference\n        }\n\n    def process_const(self) -> None:\n        if 'const' not in self.extras:\n            return None\n        self.const = True\n        self.nullable = False\n        const = self.extras['const']\n        if self.data_type.type == 'str' and isinstance(\n            const, str\n        ):  # pragma: no cover # Literal supports only str\n            self.data_type = self.data_type.__class__(literals=[const])\n\n    def _get_strict_field_constraint_value(self, constraint: str, value: Any) -> Any:\n        if value is None or constraint not in self._COMPARE_EXPRESSIONS:\n            return value\n\n        if any(\n            data_type.type == 'float' for data_type in self.data_type.all_data_types\n        ):\n            return float(value)\n        return int(value)\n\n    @property\n    def field(self) -> Optional[str]:\n        \"\"\"for backwards compatibility\"\"\"\n        result = str(self)\n        if result == '':\n            return None\n\n        return result\n\n    def __str__(self) -> str:\n        data: Dict[str, Any] = {\n            k: v for k, v in self.extras.items() if k in self._FIELD_KEYS\n        }\n        if self.alias:\n            data['name'] = self.alias\n\n        if self.default != UNDEFINED and self.default is not None:\n            data['default'] = self.default\n\n        if self.required:\n            data = {\n                k: v\n                for k, v in data.items()\n                if k\n                not in (\n                    'default',\n                    'default_factory',\n                )\n            }\n        elif self.default and 'default_factory' not in data:\n            default_factory = self._get_default_as_struct_model()\n            if default_factory is not None:\n                data.pop('default')\n                data['default_factory'] = default_factory\n\n        if not data:\n            return ''\n\n        if len(data) == 1 and 'default' in data:\n            return repr(data['default'])\n\n        kwargs = [\n            f'{k}={v if k == \"default_factory\" else repr(v)}' for k, v in data.items()\n        ]\n        return f'field({\", \".join(kwargs)})'\n\n    @property\n    def annotated(self) -> Optional[str]:\n        if not self.use_annotated:  # pragma: no cover\n            return None\n\n        data: Dict[str, Any] = {\n            k: v for k, v in self.extras.items() if k in self._META_FIELD_KEYS\n        }\n        if (\n            self.constraints is not None\n            and not self.self_reference()\n            and not self.data_type.strict\n        ):\n            data = {\n                **data,\n                **{\n                    k: self._get_strict_field_constraint_value(k, v)\n                    for k, v in self.constraints.dict().items()\n                    if k in self._META_FIELD_KEYS\n                },\n            }\n\n        meta_arguments = sorted(\n            f'{k}={repr(v)}' for k, v in data.items() if v is not None\n        )\n        if not meta_arguments:\n            return None\n\n        meta = f'Meta({\", \".join(meta_arguments)})'\n\n        if not self.required:\n            type_hint = self.data_type.type_hint\n            annotated_type = f'Annotated[{type_hint}, {meta}]'\n            return get_optional_type(annotated_type, self.data_type.use_union_operator)\n        return f'Annotated[{self.type_hint}, {meta}]'\n\n    def _get_default_as_struct_model(self) -> Optional[str]:\n        for data_type in self.data_type.data_types or (self.data_type,):\n            # TODO: Check nested data_types\n            if data_type.is_dict or self.data_type.is_union:\n                # TODO: Parse Union and dict model for default\n                continue  # pragma: no cover\n            elif data_type.is_list and len(data_type.data_types) == 1:\n                data_type = data_type.data_types[0]\n                if (  # pragma: no cover\n                    data_type.reference\n                    and (\n                        isinstance(data_type.reference.source, Struct)\n                        or isinstance(data_type.reference.source, RootModel)\n                    )\n                    and isinstance(self.default, list)\n                ):\n                    return f'lambda: {self._PARSE_METHOD}({repr(self.default)},  type=list[{data_type.alias or data_type.reference.source.class_name}])'\n            elif data_type.reference and isinstance(data_type.reference.source, Struct):\n                return f'lambda: {self._PARSE_METHOD}({repr(self.default)},  type={data_type.alias or data_type.reference.source.class_name})'\n        return None\n", "path": "datamodel_code_generator/model/msgspec.py"}]}