Current section
Files
Jump to
Current section
Files
src/scriptorium/parser/common.gleam
import gleam/bool
import gleam/list
import gleam/result
import gleam/string
import scriptorium/models/header.{type Header}
/// The default file extension for source files.
pub const filename_postfix = ".md"
const header_separator = ":"
/// An error that occurred when parsing content.
pub type ParseError {
EmptyFile
HeaderMissing
MalformedFilename
YearNotInt
MonthNotInt
DayNotInt
InvalidDate
MalformedHeader(header: String)
}
/// If the `value` is `Ok`, run `if_ok`, otherwise return `error`.
pub fn try(value: Result(a, b), error: c, if_ok: fn(a) -> Result(d, c)) {
result.try(result.replace_error(value, error), if_ok)
}
/// Parse given lines as headers.
pub fn parse_headers(headers: List(String)) -> Result(List(Header), ParseError) {
headers
|> list.map(parse_header)
|> result.all()
}
/// Parse given line as a header.
pub fn parse_header(header: String) -> Result(Header, ParseError) {
let header_parts = string.split(header, header_separator)
let parts_amount = list.length(header_parts)
use <- bool.guard(parts_amount < 2, Error(MalformedHeader(header)))
let assert Ok(name) = list.first(header_parts)
let assert Ok(rest) = list.rest(header_parts)
let value = string.join(rest, header_separator)
let name = string.trim(name)
let value = string.trim(value)
Ok(#(name, value))
}