risingwave_sqlparser/parser_v2/
number.rs1use core::ops::RangeBounds;
14
15use winnow::combinator::{cut_err, delimited};
16use winnow::error::{ContextError, StrContext};
17use winnow::{ModalParser, ModalResult, Parser};
18
19use super::{TokenStream, token};
20use crate::tokenizer::Token;
21
22pub fn token_number<S>(input: &mut S) -> ModalResult<String>
24where
25 S: TokenStream,
26{
27 token
28 .verify_map(|t| {
29 if let Token::Number(number) = t.token {
30 Some(number)
31 } else {
32 None
33 }
34 })
35 .context(StrContext::Label("number"))
36 .parse_next(input)
37}
38
39pub fn literal_uint<S>(input: &mut S) -> ModalResult<u64>
41where
42 S: TokenStream,
43{
44 token_number
45 .try_map(|s| s.parse::<u64>())
46 .context(StrContext::Label("u64"))
47 .parse_next(input)
48}
49
50pub fn literal_u32<S>(input: &mut S) -> ModalResult<u32>
52where
53 S: TokenStream,
54{
55 token_number
56 .try_map(|s| s.parse::<u32>())
57 .context(StrContext::Label("u32"))
58 .parse_next(input)
59}
60
61pub fn literal_i64<S>(input: &mut S) -> ModalResult<i64>
63where
64 S: TokenStream,
65{
66 token_number
67 .try_map(|s| s.parse::<i64>())
68 .context(StrContext::Label("i64"))
69 .parse_next(input)
70}
71
72pub fn precision_in_range<S>(
76 range: impl RangeBounds<u64> + std::fmt::Debug,
77) -> impl ModalParser<S, u64, ContextError>
78where
79 S: TokenStream,
80{
81 #[derive(Debug, thiserror::Error)]
82 #[error("precision must be in range {0}")]
83 struct OutOfRange(String);
84
85 delimited(
86 Token::LParen,
87 cut_err(literal_uint.try_map(move |v| {
88 if range.contains(&v) {
89 Ok(v)
90 } else {
91 Err(OutOfRange(format!("{:?}", range)))
92 }
93 })),
94 cut_err(Token::RParen),
95 )
96}