risingwave_sqlparser/parser_v2/number.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use core::ops::RangeBounds;
use winnow::combinator::{cut_err, delimited};
use winnow::error::{ContextError, StrContext};
use winnow::{PResult, Parser};
use super::{token, TokenStream};
use crate::tokenizer::Token;
/// Consume a [number][Token::Number] from token.
pub fn token_number<S>(input: &mut S) -> PResult<String>
where
S: TokenStream,
{
token
.verify_map(|t| {
if let Token::Number(number) = t.token {
Some(number)
} else {
None
}
})
.context(StrContext::Label("number"))
.parse_next(input)
}
/// Consume an unsigned literal integer/long
pub fn literal_uint<S>(input: &mut S) -> PResult<u64>
where
S: TokenStream,
{
token_number
.try_map(|s| s.parse::<u64>())
.context(StrContext::Label("u64"))
.parse_next(input)
}
/// Consume an unsigned literal integer
pub fn literal_u32<S>(input: &mut S) -> PResult<u32>
where
S: TokenStream,
{
token_number
.try_map(|s| s.parse::<u32>())
.context(StrContext::Label("u32"))
.parse_next(input)
}
/// Consume an literal integer
pub fn literal_i64<S>(input: &mut S) -> PResult<i64>
where
S: TokenStream,
{
token_number
.try_map(|s| s.parse::<i64>())
.context(StrContext::Label("i64"))
.parse_next(input)
}
/// Consume a precision definition in some types, e.g. `FLOAT(32)`.
///
/// The precision must be in the given range.
pub fn precision_in_range<S>(
range: impl RangeBounds<u64> + std::fmt::Debug,
) -> impl Parser<S, u64, ContextError>
where
S: TokenStream,
{
#[derive(Debug, thiserror::Error)]
#[error("precision must be in range {0}")]
struct OutOfRange(String);
delimited(
Token::LParen,
cut_err(literal_uint.try_map(move |v| {
if range.contains(&v) {
Ok(v)
} else {
Err(OutOfRange(format!("{:?}", range)))
}
})),
cut_err(Token::RParen),
)
}