use std::{
fmt::{Display, Formatter, Result},
ops::Deref,
};
use convert_case::{Case, Casing};
use itertools::Itertools;
use spacetimedb_lib::sats::AlgebraicTypeRef;
use spacetimedb_schema::{
def::ModuleDef,
identifier::Identifier,
type_for_generate::{AlgebraicTypeUse, PrimitiveType},
};
use super::code_indenter::Indenter;
pub(super) fn fmt_fn(f: impl Fn(&mut Formatter) -> Result) -> impl Display {
struct FDisplay<F>(F);
impl<F: Fn(&mut Formatter) -> Result> Display for FDisplay<F> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
(self.0)(f)
}
}
FDisplay(f)
}
pub(super) fn collect_case<'a>(case: Case, segs: impl Iterator<Item = &'a Identifier>) -> String {
segs.map(|s| s.deref().to_case(case)).join(case.delim())
}
pub(super) fn namespace_is_empty_or_default(requested_namespace: &str) -> bool {
requested_namespace.is_empty() || requested_namespace == "SpacetimeDB.Types"
}
pub(super) fn print_lines(output: &mut Indenter, lines: &[&str]) {
for line in lines {
writeln!(output, "{line}");
}
}
const AUTO_GENERATED_FILE_COMMENT: &[&str] = &[
"// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE",
"// WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD.",
"",
];
pub(super) fn print_auto_generated_file_comment(output: &mut Indenter) {
print_lines(output, AUTO_GENERATED_FILE_COMMENT);
}
pub(super) fn type_ref_name(module: &ModuleDef, typeref: AlgebraicTypeRef) -> String {
let (name, _def) = module.type_def_from_ref(typeref).unwrap();
collect_case(Case::Pascal, name.name_segments())
}
pub(super) fn is_type_filterable(ty: &AlgebraicTypeUse) -> bool {
match ty {
AlgebraicTypeUse::Primitive(prim) => !matches!(prim, PrimitiveType::F32 | PrimitiveType::F64),
AlgebraicTypeUse::String | AlgebraicTypeUse::Identity | AlgebraicTypeUse::Address => true,
_ => false,
}
}