+ The function supports type checking and throws a UsageError
+ when the value does not fit.
+ """
+ def _check_field(v: Any, field: 'dataclasses.Field[Any]') -> Any:
+ if v is None:
+ return field.default_factory() \
+ if field.default_factory != dataclasses.MISSING \
+ else field.default
+ if field.metadata and 'transform' in field.metadata:
+ return field.metadata['transform'](v)
+ if not isinstance(v, field.type):
+ raise UsageError(f"Parameter '{field.name}' needs to be of {field.type!s}.")
+ return v
+
+ return cls(**{f.name: _check_field(kwargs[f.name], f)
+ for f in dataclasses.fields(cls) if f.name in kwargs})
+
+
+@dataclasses.dataclass
+class ReverseDetails(LookupDetails):
+ """ Collection of parameters for the reverse call.
+ """
+ max_rank: int = dataclasses.field(default=30,
+ metadata={'transform': lambda v: max(0, min(v, 30))}
+ )
+ """ Highest address rank to return.
+ """
+ layers: DataLayer = DataLayer.ADDRESS | DataLayer.POI
+ """ Filter which kind of data to include.