4个版本
0.2.3 | 2022年10月27日 |
---|---|
0.2.2 | 2022年10月21日 |
0.2.1 | 2022年10月19日 |
0.2.0 | 2022年10月16日 |
#5 in #parsable
每月 25 次下载
用于 parseal
21KB
278 行
此crate定义了parseal crate的derive宏。
对于元组结构体,生成的代码应如下所示
#[derive(Parsable)]
struct Test(Number, Comma, Number);
// generated code
impl Parse for Test {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_0 = Number::parse(value)?;
let __inner_1 = Comma::parse(value)?;
let __inner_2 = Number::parse(value)?;
Ok(Self(__inner_0, __inner_1, __inner_2))
}
fn span(&self) -> Span {
Span::new(self.0.span().start, self.2.span().end)
}
}
#[derive(Parsable)]
struct TestWhiteSpace(#[whitespace(KeepAll)] [tokens::Hyphen; 3], Number);
// generated code
impl Parse for TestWhiteSpace {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_0 = {
let __white_space_value = value.clone();
__white_space_value.set_whitespace(WhiteSpaceType::KeepAll);
let inner = <[tokens::Hyphen; 3]>::parse(&mut __white_space_value);
value.goto(__white_space_value.position())?;
inner
}?;
let __inner_1 = Number::parse(value)?;
Ok(Self(__inner_0, __inner_1))
}
fn span(&self) -> Span {
Span::new(self.0.span().start, self.1.span().end)
}
}
#[derive(Parsable)]
struct TestValue(#[value("test", "other")] Identifier, Number);
// generated code
impl Parse for TestWhiteSpace {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_0 = match Identifier::parse(value) {
Ok(__inner_0) if __inner_0 == "test" => __inner_0,
Ok(__inner_0) if __inner_0 == "other" => __inner_0,
Ok(__inner_0) => return Err(ParseError("Value was not one of the expected values.", value.position())),
Err(error) => return Err(error)
};
let __inner_1 = Number::parse(value)?;
Ok(Self(__inner_0, __inner_1))
}
fn span(&self) -> Span {
Span::new(self.0.span().start, self.1.span().end)
}
}
#[derive(Parsable)]
struct TestValueWhiteSpace(#[whitespace(Indent)] #[value("test", "other")] Identifier, Number);
// generated code
impl Parse for TestWhiteSpace {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_0 = match {
let __white_space_value = value.clone();
__white_space_value.set_whitespace(WhiteSpaceType::Indent);
let inner = Identifier::parse(&mut __white_space_value);
value.goto(__white_space_value.position())?;
inner
} {
Ok(__inner_0) if __inner_0 == "test" => __inner_0,
Ok(__inner_0) if __inner_0 == "other" => __inner_0,
Ok(__inner_0) => return Err(ParseError("Value was not one of the expected values.", value.position())),
Err(error) => return Err(error)
};
let __inner_1 = Number::parse(value)?;
Ok(Self(__inner_0, __inner_1))
}
fn span(&self) -> Span {
Span::new(self.0.span().start, self.1.span().end)
}
}
对于命名结构体,它应如下所示
#[derive(Parsable)]
struct Test {
x: Number,
comma: Comma,
y: Number
}
// generated code
impl Parse for Test {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_x = Number::parse(value)?;
let __inner_comma = Comma::parse(value)?;
let __inner_y = Number::parse(value)?;
Ok(Self { x: __inner_x, comma: __inner_comma, y: __inner_y})
}
fn span(&self) -> Span {
Span::new(self.x.span().start, self.y.span().end)
}
}
#[derive(Parsable)]
struct TestWhiteSpace {
#[whitespace(Indent)]
x: Number,
comma: Comma,
y: Number
}
// generated code
impl Parse for Test {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_x = {
let __white_space_value = value.clone();
__white_space_value.set_whitespace(WhiteSpaceType::Indent);
let inner = Number::parse(&mut __white_space_value);
value.goto(__white_space_value.position())?;
inner
}?;
let __inner_comma = Comma::parse(value)?;
let __inner_y = Number::parse(value)?;
Ok(Self { x: __inner_x, comma: __inner_comma, y: __inner_y})
}
fn span(&self) -> Span {
Span::new(self.x.span().start, self.y.span().end)
}
}
#[derive(Parsable)]
struct TestValue {
#[value(69, 420)] x: Number,
comma: Comma,
y: Number
}
// generated code
impl Parse for Test {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_x = match Number::parse(value) {
Ok(__inner_x) if __inner_x == 69 => __inner_x,
Ok(__inner_x) if __inner_x == 420 => __inner_x,
Ok(__inner_x) => return Err(ParseError("Value was not one of the expected values.", value.position())),
Err(error) => return Err(error)
};
let __inner_comma = Comma::parse(value)?;
let __inner_y = Number::parse(value)?;
Ok(Self { x: __inner_x, comma: __inner_comma, y: __inner_y})
}
fn span(&self) -> Span {
Span::new(self.x.span().start, self.y.span().end)
}
}
#[derive(Parsable)]
struct TestWhiteSpaceValue {
#[whitespace(Indent)]
#[value(69, 420)]
x: Number,
comma: Comma,
y: Number
}
// generated code
impl Parse for Test {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_x = match {
let __white_space_value = value.clone();
__white_space_value.set_whitespace(WhiteSpaceType::Indent);
let inner = Number::parse(&mut __white_space_value);
value.goto(__white_space_value.position())?;
inner
} {
Ok(__inner_x) if __inner_x == 69 => __inner_x,
Ok(__inner_x) if __inner_x == 420 => __inner_x,
Ok(__inner_x) => return Err(ParseError("Value was not one of the expected values.", value.position())),
Err(error) => return Err(error)
};
let __inner_comma = Comma::parse(value)?;
let __inner_y = Number::parse(value)?;
Ok(Self { x: __inner_x, comma: __inner_comma, y: __inner_y})
}
fn span(&self) -> Span {
Span::new(self.x.span().start, self.y.span().end)
}
}
对于枚举,它看起来像这样
#[derive(Parsable)]
enum Test {
TestOne(tokens::Hyphen, Number),
TestTwo {
x: Number,
y: Number
}
}
impl Test {
fn __parse_testone(value: &mut CharStream) -> Result<Self, ParseError> {
let __inner_0 = tokens::Hyphen::parse(value)?;
let __inner_1 = Number::parse(value)?;
Ok(Self::TestOne(__inner_0, __inner_1))
}
fn __parse_testtwo(&mut CharStream) -> Result<Self, ParseError> {
let __inner_x = Number::parse(value)?;
let __inner_y = Number::parse(value)?;
Ok(Self::TestTwo(x: __inner_x, y: __inner_y))
}
}
impl Parse for Test {
fn parse(value: &mut CharStream) -> Result<Self, ParseError> {
let mut options = Vec::new();
let mut error = None;
let __value = value.clone();
match __parse_testone(__value) {
Ok(inner) => {
value.goto(__value.position());
options.push(inner);
}
Err(err) => error = Some(err);
};
let __value = value.clone();
match __parse_testtwo(__value) {
Ok(inner) => {
value.goto(__value.position());
options.push(inner);
}
Err(err) => error = Some(err);
};
if options.len() > 0 {
Ok(options.sort_by(|a, b| a.span().partial_cmp(b.span()).unwrap())[0])
} else {
Err(error.unwrap())
}
}
fn span(&self) -> Span {
match self {
Self::TestOne(start, end) => Span::new(start.span().start, end.span().end),
Self::TestTwo(x, y) => Span::new(x.span().start, y.span().end)
}
}
}
枚举的辅助属性在助手函数中的工作方式基本上与结构体相同。因此,我们目前不需要过多考虑它们的实现(我希望如此...)。
依赖项
~1.5MB
~34K SLoC