mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
191 lines
4.8 KiB
Rust
191 lines
4.8 KiB
Rust
use crate::spaces::{fmt_spaces, INDENT};
|
|
use bumpalo::collections::{String, Vec};
|
|
use roc_parse::ast::Module;
|
|
use roc_parse::header::{AppHeader, ExposesEntry, ImportsEntry, InterfaceHeader, PlatformHeader};
|
|
use roc_region::all::Located;
|
|
|
|
pub fn fmt_module<'a>(buf: &mut String<'a>, module: &'a Module<'a>) {
|
|
match module {
|
|
Module::Interface { header } => {
|
|
fmt_interface_header(buf, header);
|
|
}
|
|
Module::App { header } => {
|
|
fmt_app_header(buf, header);
|
|
}
|
|
Module::Platform { header } => {
|
|
fmt_platform_header(buf, header);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn fmt_interface_header<'a>(buf: &mut String<'a>, header: &'a InterfaceHeader<'a>) {
|
|
let indent = INDENT;
|
|
|
|
buf.push_str("interface");
|
|
|
|
// module name
|
|
if header.after_interface_keyword.is_empty() {
|
|
buf.push(' ');
|
|
} else {
|
|
fmt_spaces(buf, header.after_interface_keyword.iter(), indent);
|
|
}
|
|
|
|
buf.push_str(header.name.value.as_str());
|
|
|
|
// exposes
|
|
if header.before_exposes.is_empty() {
|
|
buf.push(' ');
|
|
} else {
|
|
fmt_spaces(buf, header.before_exposes.iter(), indent);
|
|
}
|
|
|
|
buf.push_str("exposes");
|
|
|
|
if header.after_exposes.is_empty() {
|
|
buf.push(' ');
|
|
} else {
|
|
fmt_spaces(buf, header.after_exposes.iter(), indent);
|
|
}
|
|
|
|
fmt_exposes(buf, &header.exposes, indent);
|
|
|
|
// imports
|
|
if header.before_imports.is_empty() {
|
|
buf.push(' ');
|
|
} else {
|
|
fmt_spaces(buf, header.before_imports.iter(), indent);
|
|
}
|
|
|
|
buf.push_str("imports");
|
|
|
|
if header.after_imports.is_empty() {
|
|
buf.push(' ');
|
|
} else {
|
|
fmt_spaces(buf, header.after_imports.iter(), indent);
|
|
}
|
|
|
|
fmt_imports(buf, &header.imports, indent);
|
|
}
|
|
|
|
pub fn fmt_app_header<'a>(buf: &mut String<'a>, header: &'a AppHeader<'a>) {
|
|
let indent = INDENT;
|
|
|
|
buf.push_str("app");
|
|
|
|
// imports
|
|
buf.push_str("imports");
|
|
|
|
fmt_spaces(buf, header.before_imports.iter(), indent);
|
|
fmt_imports(buf, &header.imports, indent);
|
|
fmt_spaces(buf, header.after_imports.iter(), indent);
|
|
}
|
|
|
|
pub fn fmt_platform_header<'a>(_buf: &mut String<'a>, _header: &'a PlatformHeader<'a>) {
|
|
todo!("TODO fmt platform header");
|
|
}
|
|
|
|
fn fmt_imports<'a>(
|
|
buf: &mut String<'a>,
|
|
loc_entries: &'a Vec<'a, Located<ImportsEntry<'a>>>,
|
|
indent: u16,
|
|
) {
|
|
buf.push('[');
|
|
|
|
if !loc_entries.is_empty() {
|
|
buf.push(' ');
|
|
}
|
|
|
|
for (index, loc_entry) in loc_entries.iter().enumerate() {
|
|
if index > 0 {
|
|
buf.push_str(", ");
|
|
}
|
|
|
|
fmt_imports_entry(buf, &loc_entry.value, indent);
|
|
}
|
|
|
|
if !loc_entries.is_empty() {
|
|
buf.push(' ');
|
|
}
|
|
|
|
buf.push(']');
|
|
}
|
|
|
|
fn fmt_exposes<'a>(
|
|
buf: &mut String<'a>,
|
|
loc_entries: &'a Vec<'a, Located<ExposesEntry<'a, &'a str>>>,
|
|
indent: u16,
|
|
) {
|
|
buf.push('[');
|
|
|
|
if !loc_entries.is_empty() {
|
|
buf.push(' ');
|
|
}
|
|
|
|
for (index, loc_entry) in loc_entries.iter().enumerate() {
|
|
if index > 0 {
|
|
buf.push_str(", ");
|
|
}
|
|
|
|
fmt_exposes_entry(buf, &loc_entry.value, indent);
|
|
}
|
|
|
|
if !loc_entries.is_empty() {
|
|
buf.push(' ');
|
|
}
|
|
|
|
buf.push(']');
|
|
}
|
|
|
|
fn fmt_exposes_entry<'a>(buf: &mut String<'a>, entry: &'a ExposesEntry<'a, &'a str>, indent: u16) {
|
|
use roc_parse::header::ExposesEntry::*;
|
|
|
|
match entry {
|
|
Exposed(ident) => buf.push_str(ident),
|
|
|
|
SpaceBefore(sub_entry, spaces) => {
|
|
fmt_spaces(buf, spaces.iter(), indent);
|
|
fmt_exposes_entry(buf, sub_entry, indent);
|
|
}
|
|
SpaceAfter(sub_entry, spaces) => {
|
|
fmt_exposes_entry(buf, sub_entry, indent);
|
|
fmt_spaces(buf, spaces.iter(), indent);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn fmt_imports_entry<'a>(buf: &mut String<'a>, entry: &'a ImportsEntry<'a>, indent: u16) {
|
|
use roc_parse::header::ImportsEntry::*;
|
|
|
|
match entry {
|
|
Module(module, loc_exposes_entries) => {
|
|
buf.push_str(module.as_str());
|
|
|
|
if !loc_exposes_entries.is_empty() {
|
|
buf.push_str(".{ ");
|
|
|
|
for (index, loc_entry) in loc_exposes_entries.iter().enumerate() {
|
|
if index > 0 {
|
|
buf.push_str(", ");
|
|
}
|
|
|
|
fmt_exposes_entry(buf, &loc_entry.value, indent);
|
|
}
|
|
|
|
buf.push_str(" }");
|
|
}
|
|
}
|
|
|
|
Package(_name, _entries) => {
|
|
todo!("TODO Format imported package");
|
|
}
|
|
|
|
SpaceBefore(sub_entry, spaces) => {
|
|
fmt_spaces(buf, spaces.iter(), indent);
|
|
fmt_imports_entry(buf, sub_entry, indent);
|
|
}
|
|
SpaceAfter(sub_entry, spaces) => {
|
|
fmt_imports_entry(buf, sub_entry, indent);
|
|
fmt_spaces(buf, spaces.iter(), indent);
|
|
}
|
|
}
|
|
}
|