Current section
Files
Jump to
Current section
Files
src/scriptorium/models/post.gleam
//// A post in the blog.
import gleam/int
import gleam/option.{type Option}
import gleam/order.{type Order, Eq}
import scriptorium/models/header.{type Header}
import scriptorium/utils/date.{type Date}
import scriptorium/utils/luxon.{type DateTime}
import scriptorium/utils/time.{type Time, Time}
pub type PostedAt {
/// The post only had date information.
JustDate(Date)
/// The post had date, time, and timezone information.
DateTime(date: Date, time: Time, tz: String, luxon: DateTime)
}
/// A tag is any string of lowercase characters, numbers, dashes, or underscores.
pub type Tag =
String
pub type Post {
Post(
title: String,
slug: String,
tags: List(Tag),
headers: List(Header),
content: String,
/// The content before the split, if any
short_content: Option(String),
date: PostedAt,
/// The post's order during that day, if there are multiple posts on the same day.
order: Int,
)
}
/// Get the date of the post.
pub fn get_date(post: Post) -> Date {
case post.date {
JustDate(date) -> date
DateTime(date, ..) -> date
}
}
/// Get the time of the post, if it exists.
pub fn get_time(post: Post) -> Option(Time) {
case post.date {
JustDate(..) -> option.None
DateTime(time: time, ..) -> option.Some(time)
}
}
/// Get the Luxon datetime of the post, if it exists.
pub fn get_luxon(post: Post) -> Option(luxon.DateTime) {
case post.date {
JustDate(..) -> option.None
DateTime(luxon: luxon, ..) -> option.Some(luxon)
}
}
/// Compare two posts and get an order between them.
pub fn comparator(a: Post, b: Post) -> Order {
let a_date = get_date(a)
let b_date = get_date(b)
case date.compare(a_date, b_date) {
Eq -> {
let a_time = option.lazy_unwrap(get_time(a), time.nil_time)
let b_time = option.lazy_unwrap(get_time(b), time.nil_time)
case time.compare(a_time, b_time) {
Eq -> int.compare(a.order, b.order)
other -> other
}
}
other -> other
}
}
/// Get the post's date or datetime formatted as an ISO 8601 formatted string.
pub fn to_iso8601(post: Post) -> String {
case post.date {
JustDate(d) -> date.format_iso(d)
DateTime(luxon: l, ..) -> luxon.to_iso(l)
}
}