PyC API: utility to parse a string as an RNA like enum

More convenient than comparing strings,
with the advantage that errors don't need to repeat expected values.
This commit is contained in:
2019-10-01 04:09:33 +10:00
parent ddb157999e
commit 07feb6e814
2 changed files with 42 additions and 0 deletions

View File

@@ -231,6 +231,37 @@ int PyC_ParseBool(PyObject *o, void *p)
return 1;
}
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*/
int PyC_ParseStringEnum(PyObject *o, void *p)
{
struct PyC_StringEnum *e = p;
const char *value = _PyUnicode_AsString(o);
if (value == NULL) {
PyErr_Format(PyExc_ValueError, "expected a string, got %s", Py_TYPE(o)->tp_name);
return 0;
}
int i;
for (i = 0; e->items[i].id; i++) {
if (STREQ(e->items[i].id, value)) {
e->value_found = e->items[i].value;
return 1;
}
}
/* Set as a precaution. */
e->value_found = -1;
PyObject *enum_items = PyTuple_New(i);
for (i = 0; e->items[i].id; i++) {
PyTuple_SET_ITEM(enum_items, i, PyUnicode_FromString(e->items[i].id));
}
PyErr_Format(PyExc_ValueError, "expected a string in %S, got '%s'", enum_items, value);
Py_DECREF(enum_items);
return 0;
}
/* silly function, we dont use arg. just check its compatible with __deepcopy__ */
int PyC_CheckArgs_DeepCopy(PyObject *args)
{

View File

@@ -126,6 +126,17 @@ bool PyC_RunString_AsString(const char **imports,
int PyC_ParseBool(PyObject *o, void *p);
struct PyC_StringEnumItems {
int value;
const char *id;
};
struct PyC_StringEnum {
const struct PyC_StringEnumItems *items;
int value_found;
};
int PyC_ParseStringEnum(PyObject *o, void *p);
int PyC_CheckArgs_DeepCopy(PyObject *args);
/* Integer parsing (with overflow checks), -1 on error. */