use crate::refs_impl::ast::{
OFAst, OFCellRange, OFCellRef, OFCol, OFColRange, OFIri, OFRow, OFRowRange, OFSheetName,
};
use crate::refs_impl::error::OFCode::*;
use crate::refs_impl::error::{LocateError, ParseOFError};
use crate::refs_impl::tokens::eat_space;
use crate::refs_impl::tokens::nomtokens::space;
use crate::refs_impl::{conv, map_err, tokens, ParseResult, Span};
pub(crate) fn parse_cell_range_list<'s>(
rest: Span<'s>,
) -> ParseResult<'s, Option<Vec<OFCellRange<'s>>>> {
let mut vec = Vec::new();
let mut rest_loop = rest;
loop {
rest_loop = match parse_cell_range(rest_loop) {
Ok((rest1, cell_range)) => {
vec.push(cell_range);
rest1
}
Err(e) if e.code == OFCCellRange => break,
Err(e) => return map_err(e, OFCUnexpected),
};
rest_loop = match space(rest_loop) {
Ok((rest1, _sp)) => rest1,
Err(nom::Err::Error(e)) if e.code == nom::error::ErrorKind::Tag => break,
Err(e) => return Err(ParseOFError::nom(e)),
};
}
if vec.is_empty() {
Ok((rest_loop, None))
} else {
Ok((rest_loop, Some(vec)))
}
}
pub(crate) fn parse_cell_range<'s>(rest: Span<'s>) -> ParseResult<'s, OFCellRange<'s>> {
let (rest, iri) = parse_iri(eat_space(rest))?;
let (rest, table) = parse_sheet_name(eat_space(rest))?;
let (rest, _dot) = parse_dot(eat_space(rest))?;
let (rest, col) = parse_col_term(eat_space(rest))?;
let (rest, row) = parse_row_term(rest)?;
let (rest, _colon) = parse_colon_term(eat_space(rest))?;
let (rest, to_table) = parse_sheet_name(eat_space(rest))?;
let (rest, _to_dot) = parse_dot(eat_space(rest))?;
let (rest, to_col) = parse_col_term(eat_space(rest))?;
let (rest, to_row) = parse_row_term(rest)?;
let ast = OFCellRange {
iri,
table,
row,
col,
to_table,
to_row,
to_col,
};
Ok((rest, ast))
}
pub(crate) fn parse_cell_ref<'s>(rest: Span<'s>) -> ParseResult<'s, OFCellRef<'s>> {
let (rest, iri) = parse_iri(eat_space(rest))?;
let (rest, table) = parse_sheet_name(eat_space(rest))?;
let (rest, _dot) = parse_dot(eat_space(rest))?;
let (rest, col) = parse_col_term(eat_space(rest))?;
let (rest, row) = parse_row_term(rest)?;
let ast = OFCellRef {
iri,
table,
row,
col,
};
Ok((rest, ast))
}
#[allow(unused)]
pub(crate) fn parse_col_range<'s>(rest: Span<'s>) -> ParseResult<'s, OFColRange<'s>> {
let (rest, iri) = parse_iri(eat_space(rest))?;
let (rest, table) = parse_sheet_name(eat_space(rest))?;
let (rest, _dot) = parse_dot(eat_space(rest))?;
let (rest, col) = parse_col_term(eat_space(rest))?;
let (rest, _colon) = parse_colon_term(eat_space(rest))?;
let (rest, to_table) = parse_sheet_name(eat_space(rest))?;
let (rest, _to_dot) = parse_dot(eat_space(rest))?;
let (rest, to_col) = parse_col_term(eat_space(rest))?;
let ast = OFColRange {
iri,
table,
col,
to_table,
to_col,
};
Ok((rest, ast))
}
#[allow(unused)]
pub(crate) fn parse_row_range<'s>(rest: Span<'s>) -> ParseResult<'s, OFRowRange<'s>> {
let (rest, iri) = parse_iri(eat_space(rest))?;
let (rest, table) = parse_sheet_name(eat_space(rest))?;
let (rest, _dot) = parse_dot(eat_space(rest))?;
let (rest, row) = parse_row_term(eat_space(rest))?;
let (rest, _colon) = parse_colon_term(eat_space(rest))?;
let (rest, to_table) = parse_sheet_name(eat_space(rest))?;
let (rest, _to_dot) = parse_dot(eat_space(rest))?;
let (rest, to_row) = parse_row_term(eat_space(rest))?;
let ast = OFRowRange {
iri,
table,
row,
to_table,
to_row,
};
Ok((rest, ast))
}
#[allow(unused)]
fn parse_iri<'s>(rest: Span<'s>) -> ParseResult<'s, Option<OFIri<'s>>> {
match tokens::iri(eat_space(rest)) {
Ok((rest1, iri)) => {
let term = OFAst::iri(conv::unquote_single(iri));
Ok((rest1, Some(term)))
}
Err(e) if e.code == OFCSingleQuoteStart || e.code == OFCHashtag => Ok((rest, None)),
Err(e) if e.code == OFCString => map_err(e, OFCIri),
Err(e) if e.code == OFCSingleQuoteEnd => map_err(e, OFCIri),
Err(e) => map_err(e, OFCUnexpected),
}
}
fn parse_sheet_name<'s>(rest: Span<'s>) -> ParseResult<'s, Option<OFSheetName<'s>>> {
let (rest, sheet_name) = match tokens::sheet_name(eat_space(rest)) {
Ok((rest1, (abs, sheet_name))) => {
let term = OFAst::sheet_name(
conv::try_bool_from_abs_flag(abs),
conv::unquote_single(sheet_name),
);
(rest1, Some(term))
}
Err(e) if e.code == OFCSingleQuoteStart => (rest, None),
Err(e) if e.code == OFCSheetName => (rest, None),
Err(e) if e.code == OFCString => return map_err(e, OFCSheetName),
Err(e) if e.code == OFCSingleQuoteEnd => return map_err(e, OFCSheetName),
Err(e) => return map_err(e, OFCUnexpected),
};
Ok((rest, sheet_name))
}
#[allow(unused)]
fn parse_dot<'s>(rest: Span<'s>) -> ParseResult<'s, Span<'s>> {
let (rest, dot) = match tokens::dot(eat_space(rest)) {
Ok((rest1, dot)) => (rest1, dot),
Err(e) if e.code == OFCDot => return map_err(e, OFCDot),
Err(e) => return map_err(e, OFCUnexpected),
};
Ok((rest, dot))
}
#[allow(unused)]
fn parse_col_term<'s>(rest: Span<'s>) -> ParseResult<'s, OFCol<'s>> {
let (rest, col) = match tokens::col(rest) {
Ok((rest, col)) => (rest, col),
Err(e) if e.code == OFCAlpha => return map_err(e, OFCCol),
Err(e) => return map_err(e, OFCUnexpected),
};
let col = OFAst::col(
conv::try_bool_from_abs_flag(col.0),
conv::try_u32_from_colname(col.1).locate_err(rest)?,
);
Ok((rest, col))
}
#[allow(unused)]
fn parse_row_term<'s>(rest: Span<'s>) -> ParseResult<'s, OFRow<'s>> {
let (rest, row) = match tokens::row(rest) {
Ok((rest, row)) => (rest, row),
Err(e) if e.code == OFCDigit => return map_err(e, OFCRow),
Err(e) => return map_err(e, OFCUnexpected),
};
let row = OFAst::row(
conv::try_bool_from_abs_flag(row.0),
conv::try_u32_from_rowname(row.1).locate_err(rest)?,
);
Ok((rest, row))
}
fn parse_colon_term<'s>(rest: Span<'s>) -> ParseResult<'s, ()> {
let (rest, _colon) = match tokens::colon(eat_space(rest)) {
Ok((rest1, dot)) => (rest1, dot),
Err(e) if e.code == OFCColon => return map_err(e, OFCColon),
Err(e) => return map_err(e, OFCUnexpected),
};
Ok((rest, ()))
}