"""NACA-family airfoil schema dataclasses."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Literal
from buffalo_core.schema import SchemaChoice, SchemaField
from buffalo_core.typing import FloatScalar
[docs]
@dataclass(slots=True)
class Naca4AirfoilParamsSpec:
"""Explicit parameter definition for a NACA 4-digit airfoil."""
#: Maximum camber as a fraction of chord.
m: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Camber",
order=10,
short_help="Maximum camber as a fraction of chord.",
default=0.0,
minimum=0.0,
exclusive_maximum=0.1,
).to_metadata(),
)
#: Chordwise location of maximum camber as a fraction of chord.
p: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Camber Location",
order=20,
short_help="Chordwise location of maximum camber.",
default=0.0,
minimum=0.0,
maximum=0.9,
notes="Must be 0 when m is 0 and positive when m is positive.",
).to_metadata(),
)
#: Maximum thickness as a fraction of chord.
max_thickness: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Thickness",
order=30,
short_help="Maximum thickness as a fraction of chord.",
default=0.0,
minimum=0.0,
maximum=0.4,
).to_metadata(),
)
#: Trailing-edge closure convention for the thickness law.
trailing_edge: Literal["standard", "sharp"] = field(
default="standard",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Trailing Edge",
order=40,
short_help="Trailing-edge closure convention.",
default="standard",
choices=("standard", "sharp"),
).to_metadata(),
)
#: Leading-edge radius convention for the thickness law.
leading_edge_radius: Literal["standard", "exact"] = field(
default="standard",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Leading Edge Radius",
order=50,
short_help="Leading-edge radius convention.",
default="standard",
choices=("standard", "exact"),
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca4AirfoilSpec:
"""Schema definition for a NACA 4-digit airfoil."""
#: Schema discriminator for a NACA 4-digit airfoil.
type: Literal["naca4"] = field(
default="naca4",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for a NACA 4-digit airfoil.",
default="naca4",
choices=(SchemaChoice(value="naca4", label="NACA 4-Digit"),),
).to_metadata(),
)
#: Encoded NACA 4-digit designation such as ``"2412"``.
designation: str | None = field(
default=None,
metadata=SchemaField(
value_kind="string",
required=False,
label="Designation",
order=20,
short_help="Encoded NACA 4-digit designation string.",
format_hint="####",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
#: Explicit parameter form used instead of ``designation``.
params: Naca4AirfoilParamsSpec | None = field(
default=None,
metadata=SchemaField(
value_kind="object",
required=False,
label="Parameters",
order=30,
short_help="Explicit NACA 4-digit parameter block.",
item_kind="Naca4AirfoilParamsSpec",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca4ModifiedAirfoilParamsSpec:
"""Explicit parameter definition for a modified NACA 4-digit airfoil."""
#: Maximum camber as a fraction of chord.
m: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Camber",
order=10,
short_help="Maximum camber as a fraction of chord.",
default=0.0,
minimum=0.0,
exclusive_maximum=0.1,
).to_metadata(),
)
#: Chordwise location of maximum camber as a fraction of chord.
p: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Camber Location",
order=20,
short_help="Chordwise location of maximum camber.",
default=0.0,
minimum=0.0,
maximum=0.9,
notes="Must be 0 when m is 0 and positive when m is positive.",
).to_metadata(),
)
#: Maximum thickness as a fraction of chord.
max_thickness: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Thickness",
order=30,
short_help="Maximum thickness as a fraction of chord.",
default=0.0,
minimum=0.0,
maximum=0.4,
).to_metadata(),
)
#: Leading-edge index in the modified NACA thickness family.
leading_edge_index: FloatScalar = field(
default=1.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Leading Edge Index",
order=40,
short_help="Modified-family leading-edge index.",
default=1.0,
minimum=1.0,
exclusive_maximum=10.0,
).to_metadata(),
)
#: Chordwise location of maximum thickness as a fraction of chord.
max_thickness_location: FloatScalar = field(
default=0.1,
metadata=SchemaField(
value_kind="number",
required=False,
label="Thickness Location",
order=50,
short_help="Chordwise location of maximum thickness.",
default=0.1,
minimum=0.1,
exclusive_maximum=1.0,
).to_metadata(),
)
#: Trailing-edge closure convention for the thickness law.
trailing_edge: Literal["standard", "sharp"] = field(
default="standard",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Trailing Edge",
order=60,
short_help="Trailing-edge closure convention.",
default="standard",
choices=("standard", "sharp"),
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca4ModifiedAirfoilSpec:
"""Schema definition for a modified NACA 4-digit airfoil."""
#: Schema discriminator for a modified NACA 4-digit airfoil.
type: Literal["naca4_modified"] = field(
default="naca4_modified",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help=(
"Schema discriminator for a modified NACA 4-digit airfoil."
),
default="naca4_modified",
choices=(
SchemaChoice(
value="naca4_modified",
label="NACA 4-Digit Modified",
),
),
).to_metadata(),
)
#: Encoded modified NACA designation.
designation: str | None = field(
default=None,
metadata=SchemaField(
value_kind="string",
required=False,
label="Designation",
order=20,
short_help="Encoded modified NACA 4-digit designation string.",
format_hint="####-##",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
#: Explicit parameter form used instead of ``designation``.
params: Naca4ModifiedAirfoilParamsSpec | None = field(
default=None,
metadata=SchemaField(
value_kind="object",
required=False,
label="Parameters",
order=30,
short_help="Explicit modified NACA 4-digit parameter block.",
item_kind="Naca4ModifiedAirfoilParamsSpec",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca5AirfoilParamsSpec:
"""Explicit parameter definition for a NACA 5-digit airfoil."""
#: Ideal lift coefficient associated with the mean line.
ideal_lift_coefficient: FloatScalar = field(
default=0.3,
metadata=SchemaField(
value_kind="number",
required=False,
label="Ideal Lift Coefficient",
order=10,
short_help="Ideal lift coefficient for the mean line.",
default=0.3,
minimum=0.15,
exclusive_maximum=0.6,
).to_metadata(),
)
#: Chordwise location of maximum camber as a fraction of chord.
max_camber_location: FloatScalar = field(
default=0.15,
metadata=SchemaField(
value_kind="number",
required=False,
label="Camber Location",
order=20,
short_help="Chordwise location of maximum camber.",
default=0.15,
minimum=0.05,
exclusive_maximum=0.3,
).to_metadata(),
)
#: Whether to use the reflexed 5-digit mean line.
reflexed: bool = field(
default=False,
metadata=SchemaField(
value_kind="boolean",
required=False,
label="Reflexed",
order=30,
short_help="Whether to use the reflexed mean line.",
default=False,
).to_metadata(),
)
#: Maximum thickness as a fraction of chord.
max_thickness: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Thickness",
order=40,
short_help="Maximum thickness as a fraction of chord.",
default=0.0,
minimum=0.0,
maximum=0.4,
).to_metadata(),
)
#: Trailing-edge closure convention for the thickness law.
trailing_edge: Literal["standard", "sharp"] = field(
default="standard",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Trailing Edge",
order=50,
short_help="Trailing-edge closure convention.",
default="standard",
choices=("standard", "sharp"),
).to_metadata(),
)
#: Leading-edge radius convention for the thickness law.
leading_edge_radius: Literal["standard", "exact"] = field(
default="standard",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Leading Edge Radius",
order=60,
short_help="Leading-edge radius convention.",
default="standard",
choices=("standard", "exact"),
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca5AirfoilSpec:
"""Schema definition for a NACA 5-digit airfoil."""
#: Schema discriminator for a NACA 5-digit airfoil.
type: Literal["naca5"] = field(
default="naca5",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for a NACA 5-digit airfoil.",
default="naca5",
choices=(SchemaChoice(value="naca5", label="NACA 5-Digit"),),
).to_metadata(),
)
#: Encoded NACA 5-digit designation such as ``"23012"``.
designation: str | None = field(
default=None,
metadata=SchemaField(
value_kind="string",
required=False,
label="Designation",
order=20,
short_help="Encoded NACA 5-digit designation string.",
format_hint="#####",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
#: Explicit parameter form used instead of ``designation``.
params: Naca5AirfoilParamsSpec | None = field(
default=None,
metadata=SchemaField(
value_kind="object",
required=False,
label="Parameters",
order=30,
short_help="Explicit NACA 5-digit parameter block.",
item_kind="Naca5AirfoilParamsSpec",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca5ModifiedAirfoilParamsSpec:
"""Explicit parameter definition for a modified NACA 5-digit airfoil."""
#: Ideal lift coefficient associated with the mean line.
ideal_lift_coefficient: FloatScalar = field(
default=0.3,
metadata=SchemaField(
value_kind="number",
required=False,
label="Ideal Lift Coefficient",
order=10,
short_help="Ideal lift coefficient for the mean line.",
default=0.3,
minimum=0.15,
exclusive_maximum=0.6,
).to_metadata(),
)
#: Chordwise location of maximum camber as a fraction of chord.
max_camber_location: FloatScalar = field(
default=0.15,
metadata=SchemaField(
value_kind="number",
required=False,
label="Camber Location",
order=20,
short_help="Chordwise location of maximum camber.",
default=0.15,
minimum=0.05,
exclusive_maximum=0.3,
).to_metadata(),
)
#: Whether to use the reflexed 5-digit mean line.
reflexed: bool = field(
default=False,
metadata=SchemaField(
value_kind="boolean",
required=False,
label="Reflexed",
order=30,
short_help="Whether to use the reflexed mean line.",
default=False,
).to_metadata(),
)
#: Maximum thickness as a fraction of chord.
max_thickness: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Thickness",
order=40,
short_help="Maximum thickness as a fraction of chord.",
default=0.0,
minimum=0.0,
maximum=0.4,
).to_metadata(),
)
#: Leading-edge index in the modified NACA thickness family.
leading_edge_index: FloatScalar = field(
default=1.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Leading Edge Index",
order=50,
short_help="Modified-family leading-edge index.",
default=1.0,
minimum=1.0,
exclusive_maximum=10.0,
).to_metadata(),
)
#: Chordwise location of maximum thickness as a fraction of chord.
max_thickness_location: FloatScalar = field(
default=0.1,
metadata=SchemaField(
value_kind="number",
required=False,
label="Thickness Location",
order=60,
short_help="Chordwise location of maximum thickness.",
default=0.1,
minimum=0.1,
exclusive_maximum=1.0,
).to_metadata(),
)
#: Trailing-edge closure convention for the thickness law.
trailing_edge: Literal["standard", "sharp"] = field(
default="standard",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Trailing Edge",
order=70,
short_help="Trailing-edge closure convention.",
default="standard",
choices=("standard", "sharp"),
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca5ModifiedAirfoilSpec:
"""Schema definition for a modified NACA 5-digit airfoil."""
#: Schema discriminator for a modified NACA 5-digit airfoil.
type: Literal["naca5_modified"] = field(
default="naca5_modified",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help=(
"Schema discriminator for a modified NACA 5-digit airfoil."
),
default="naca5_modified",
choices=(
SchemaChoice(
value="naca5_modified",
label="NACA 5-Digit Modified",
),
),
).to_metadata(),
)
#: Encoded modified NACA 5-digit designation.
designation: str | None = field(
default=None,
metadata=SchemaField(
value_kind="string",
required=False,
label="Designation",
order=20,
short_help="Encoded modified NACA 5-digit designation string.",
format_hint="#####-##",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
#: Explicit parameter form used instead of ``designation``.
params: Naca5ModifiedAirfoilParamsSpec | None = field(
default=None,
metadata=SchemaField(
value_kind="object",
required=False,
label="Parameters",
order=30,
short_help="Explicit modified NACA 5-digit parameter block.",
item_kind="Naca5ModifiedAirfoilParamsSpec",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca16AirfoilParamsSpec:
"""Explicit parameter definition for a NACA 16-series airfoil."""
#: Ideal lift coefficient encoded by the designation family.
ideal_lift_coefficient: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Ideal Lift Coefficient",
order=10,
short_help="Ideal lift coefficient encoded by the family.",
default=0.0,
minimum=0.0,
maximum=0.9,
).to_metadata(),
)
#: Maximum thickness as a fraction of chord.
max_thickness: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Thickness",
order=20,
short_help="Maximum thickness as a fraction of chord.",
default=0.0,
exclusive_minimum=0.0,
maximum=0.4,
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca16AirfoilSpec:
"""Schema definition for a NACA 16-series airfoil."""
#: Schema discriminator for a NACA 16-series airfoil.
type: Literal["naca16"] = field(
default="naca16",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for a NACA 16-series airfoil.",
default="naca16",
choices=(SchemaChoice(value="naca16", label="NACA 16-Series"),),
).to_metadata(),
)
#: Encoded NACA 16-series designation such as ``"16-312"``.
designation: str | None = field(
default=None,
metadata=SchemaField(
value_kind="string",
required=False,
label="Designation",
order=20,
short_help="Encoded NACA 16-series designation string.",
format_hint="16-###",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
#: Explicit parameter form used instead of ``designation``.
params: Naca16AirfoilParamsSpec | None = field(
default=None,
metadata=SchemaField(
value_kind="object",
required=False,
label="Parameters",
order=30,
short_help="Explicit NACA 16-series parameter block.",
item_kind="Naca16AirfoilParamsSpec",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6ThicknessSpec:
"""Thickness inputs for a NACA 6-series airfoil definition."""
#: NACA 6-series family token such as ``"65"``.
series: str = field(
default="",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Series",
order=10,
short_help="NACA 6-series family token.",
default="",
choices=("63", "64", "65", "66", "67"),
).to_metadata(),
)
#: Maximum thickness as a fraction of chord.
max_thickness: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Thickness",
order=20,
short_help="Maximum thickness as a fraction of chord.",
default=0.0,
minimum=0.0,
maximum=0.4,
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6CamberComponentSpec:
"""One additive mean-line component for a NACA 6-series airfoil."""
#: Ideal lift coefficient for this additive mean-line component.
ideal_lift_coefficient: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Ideal Lift Coefficient",
order=10,
short_help="Ideal lift coefficient for one camber component.",
default=0.0,
minimum=-0.5,
maximum=0.5,
notes=(
"Single-component definitions effectively use 0 <= value "
"<= 0.5."
),
).to_metadata(),
)
#: Mean-line shape parameter for this component.
mean_line_shape_parameter: FloatScalar | None = field(
default=None,
metadata=SchemaField(
value_kind="number",
required=False,
label="Mean Line Shape",
order=20,
short_help="Mean-line shape parameter for this component.",
minimum=0.0,
maximum=1.0,
notes="Required for multi-component NACA 6-series definitions.",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6CamberSpec:
"""Camber inputs for a NACA 6-series airfoil definition."""
#: Ordered list of additive mean-line components.
components: list[Naca6CamberComponentSpec] = field(
default_factory=list,
metadata=SchemaField(
value_kind="list",
required=False,
label="Components",
order=10,
short_help="Ordered additive mean-line components.",
min_items=1,
item_kind="Naca6CamberComponentSpec",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6AirfoilParamsSpec:
"""Explicit parameter definition for a NACA 6-series airfoil."""
#: Thickness-family inputs for the NACA 6-series definition.
thickness: Naca6ThicknessSpec = field(
default_factory=Naca6ThicknessSpec,
metadata=SchemaField(
value_kind="object",
required=False,
label="Thickness",
order=10,
short_help="Thickness-family inputs for the 6-series definition.",
item_kind="Naca6ThicknessSpec",
).to_metadata(),
)
#: Camber-line inputs for the NACA 6-series definition.
camber: Naca6CamberSpec = field(
default_factory=Naca6CamberSpec,
metadata=SchemaField(
value_kind="object",
required=False,
label="Camber",
order=20,
short_help="Camber-line inputs for the 6-series definition.",
item_kind="Naca6CamberSpec",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6AirfoilSpec:
"""Schema definition for a NACA 6-series airfoil."""
#: Schema discriminator for a NACA 6-series airfoil.
type: Literal["naca6"] = field(
default="naca6",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for a NACA 6-series airfoil.",
default="naca6",
choices=(SchemaChoice(value="naca6", label="NACA 6-Series"),),
).to_metadata(),
)
#: Historical NACA 6-series designation string.
designation: str | None = field(
default=None,
metadata=SchemaField(
value_kind="string",
required=False,
label="Designation",
order=20,
short_help="Historical NACA 6-series designation string.",
format_hint="65-210 or 65(1)-212",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
#: Explicit parameter form used instead of ``designation``.
params: Naca6AirfoilParamsSpec | None = field(
default=None,
metadata=SchemaField(
value_kind="object",
required=False,
label="Parameters",
order=30,
short_help="Explicit NACA 6-series parameter block.",
item_kind="Naca6AirfoilParamsSpec",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6AThicknessSpec:
"""Thickness inputs for a NACA 6A-series airfoil definition."""
#: NACA 6A-series family token such as ``"65A"``.
series: str = field(
default="",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Series",
order=10,
short_help="NACA 6A-series family token.",
default="",
choices=("63A", "64A", "65A"),
).to_metadata(),
)
#: Maximum thickness as a fraction of chord.
max_thickness: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Maximum Thickness",
order=20,
short_help="Maximum thickness as a fraction of chord.",
default=0.0,
minimum=0.0,
maximum=0.4,
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6ACamberComponentSpec:
"""One additive mean-line component for a NACA 6A-series airfoil."""
#: Ideal lift coefficient for this additive mean-line component.
ideal_lift_coefficient: FloatScalar = field(
default=0.0,
metadata=SchemaField(
value_kind="number",
required=False,
label="Ideal Lift Coefficient",
order=10,
short_help="Ideal lift coefficient for one camber component.",
default=0.0,
minimum=-0.5,
maximum=0.5,
notes=(
"Single-component definitions effectively use 0 <= value "
"<= 0.5."
),
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6ACamberSpec:
"""Camber inputs for a NACA 6A-series airfoil definition."""
#: Ordered list of additive mean-line components.
components: list[Naca6ACamberComponentSpec] = field(
default_factory=list,
metadata=SchemaField(
value_kind="list",
required=False,
label="Components",
order=10,
short_help="Ordered additive mean-line components.",
min_items=1,
item_kind="Naca6ACamberComponentSpec",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6AAirfoilParamsSpec:
"""Explicit parameter definition for a NACA 6A-series airfoil."""
#: Thickness-family inputs for the NACA 6A-series definition.
thickness: Naca6AThicknessSpec = field(
default_factory=Naca6AThicknessSpec,
metadata=SchemaField(
value_kind="object",
required=False,
label="Thickness",
order=10,
short_help="Thickness-family inputs for the 6A-series.",
item_kind="Naca6AThicknessSpec",
).to_metadata(),
)
#: Camber-line inputs for the NACA 6A-series definition.
camber: Naca6ACamberSpec = field(
default_factory=Naca6ACamberSpec,
metadata=SchemaField(
value_kind="object",
required=False,
label="Camber",
order=20,
short_help="Camber-line inputs for the 6A-series.",
item_kind="Naca6ACamberSpec",
).to_metadata(),
)
[docs]
@dataclass(slots=True)
class Naca6AAirfoilSpec:
"""Schema definition for a NACA 6A-series airfoil."""
#: Schema discriminator for a NACA 6A-series airfoil.
type: Literal["naca6a"] = field(
default="naca6a",
metadata=SchemaField(
value_kind="enum",
required=False,
label="Type",
order=10,
short_help="Schema discriminator for a NACA 6A-series airfoil.",
default="naca6a",
choices=(SchemaChoice(value="naca6a", label="NACA 6A-Series"),),
).to_metadata(),
)
#: Historical NACA 6A-series designation string.
designation: str | None = field(
default=None,
metadata=SchemaField(
value_kind="string",
required=False,
label="Designation",
order=20,
short_help="Historical NACA 6A-series designation string.",
format_hint="64A-212",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)
#: Explicit parameter form used instead of ``designation``.
params: Naca6AAirfoilParamsSpec | None = field(
default=None,
metadata=SchemaField(
value_kind="object",
required=False,
label="Parameters",
order=30,
short_help="Explicit NACA 6A-series parameter block.",
item_kind="Naca6AAirfoilParamsSpec",
notes="Provide exactly one of designation or params.",
).to_metadata(),
)