s_text_input_f_parser/
lib.rs1use chumsky::prelude::*;
2use s_text_input_f::{Block, BlocksWithAnswer};
3
4impl FromIterator<CorrectBlock> for BlocksWithAnswer {
5 fn from_iter<T: IntoIterator<Item = CorrectBlock>>(iter: T) -> Self {
6 let (blocks, answer) = iter.into_iter().map(|x| (x.block, x.answer)).unzip();
7 Self { blocks, answer }
8 }
9}
10
11#[derive(Debug)]
12pub struct CorrectBlock {
13 pub block: Block,
14 pub answer: Vec<String>,
15}
16impl From<paragraph::CorrectParagraph> for CorrectBlock {
17 fn from(value: paragraph::CorrectParagraph) -> Self {
18 Self {
19 block: Block::Paragraph(value.input),
20 answer: value.answer,
21 }
22 }
23}
24impl From<one_of::CorrectOneOf> for CorrectBlock {
25 fn from(value: one_of::CorrectOneOf) -> Self {
26 Self {
27 block: Block::OneOf(value.variants),
28 answer: vec![value.correct.to_string()],
29 }
30 }
31}
32impl From<any_of::CorrectAnyOf> for CorrectBlock {
33 fn from(value: any_of::CorrectAnyOf) -> Self {
34 Self {
35 block: Block::AnyOf(value.variants),
36 answer: value.correct.into_iter().map(|x| x.to_string()).collect(),
37 }
38 }
39}
40
41pub fn parse_paragraph(input: &str) -> Result<paragraph::CorrectParagraph, Vec<Simple<char>>> {
42 paragraph::paragraph_parser()
43 .then_ignore(end())
44 .parse(input)
45}
46pub fn parse_one_of(input: &str) -> Result<one_of::CorrectOneOf, Vec<Simple<char>>> {
47 one_of::one_of_parser().then_ignore(end()).parse(input)
48}
49pub fn parse_any_of(input: &str) -> Result<any_of::CorrectAnyOf, Vec<Simple<char>>> {
50 any_of::any_of_parser().then_ignore(end()).parse(input)
51}
52
53pub mod any_of;
54pub mod one_of;
55pub mod paragraph;
56
57pub fn parse_block(input: &str) -> Result<CorrectBlock, Vec<Simple<char>>> {
58 block_parser().then_ignore(end()).parse(input)
59}
60
61fn block_parser() -> impl Parser<char, CorrectBlock, Error = Simple<char>> {
62 choice((
63 any_of::any_of_parser().map(CorrectBlock::from),
64 one_of::one_of_parser().map(CorrectBlock::from),
65 paragraph::paragraph_parser().map(CorrectBlock::from),
66 ))
68}
69
70pub fn parse_blocks(input: &str) -> Result<BlocksWithAnswer, Vec<Simple<char>>> {
71 blocks_parser().then_ignore(end()).parse(input)
72}
73fn blocks_parser() -> impl Parser<char, BlocksWithAnswer, Error = Simple<char>> {
74 block_parser()
75 .separated_by(just('\n').repeated().at_least(1))
76 .at_least(1)
77 .collect()
78}