skip to content
==> include/mesh/rs_parse.h <==
1/* @ajax/mesh-rs-parse: integers parsed exactly as Rust's `str::parse::<uN/iN>()` and
2 * `uN::from_str_radix` do: an optional '+' (or '-' for signed types), then at least one digit of the
3 * radix and nothing else (no spaces, no prefix), and a value that fits the type. Strings are
4 * (pointer, length), so a word inside a longer line parses without a copy. */
5#ifndef MESH_RS_PARSE_H
6#define MESH_RS_PARSE_H
7
8#include <stdbool.h>
9#include <stddef.h>
10#include <stdint.h>
11
12/* Unsigned, at most max (UINT64_MAX for u64, UINT32_MAX for u32, ...), radix 2..36. */
13bool rs_parse_uint(const char *s, size_t n, unsigned radix, uint64_t max, uint64_t *out);
14/* Signed, in [min, max], radix 10. */
15bool rs_parse_int(const char *s, size_t n, int64_t min, int64_t max, int64_t *out);
16
17static inline bool rs_u64(const char *s, size_t n, uint64_t *out) { return rs_parse_uint(s, n, 10, UINT64_MAX, out); }
18static inline bool rs_u32(const char *s, size_t n, uint32_t *out) {
19    uint64_t v;
20    if (!rs_parse_uint(s, n, 10, UINT32_MAX, &v)) return false;
21    *out = (uint32_t)v;
22    return true;
23}
24static inline bool rs_i32(const char *s, size_t n, int32_t *out) {
25    int64_t v;
26    if (!rs_parse_int(s, n, INT32_MIN, INT32_MAX, &v)) return false;
27    *out = (int32_t)v;
28    return true;
29}
30
31#endif