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
78#include <stdbool.h>
9#include <stddef.h>
10#include <stdint.h>
1112/* 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);
1617static 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}
3031#endif