use core::fmt::Write as _;
use alloc::collections::BTreeSet;
use crate::fmt;
use crate::tokens::ItemStr;
pub type Tokens = crate::Tokens<Swift>;
impl_lang! {
pub Swift {
type Config = Config;
type Format = Format;
type Item = Any;
fn write_quoted(out: &mut fmt::Formatter<'_>, input: &str) -> fmt::Result {
for c in input.chars() {
match c {
'\0' => out.write_str("\\0")?,
'\\' => out.write_str("\\\\")?,
'\t' => out.write_str("\\t")?,
'\n' => out.write_str("\\n")?,
'\r' => out.write_str("\\r")?,
'\'' => out.write_str("\\'")?,
'"' => out.write_str("\\\"")?,
c if !c.is_control() => out.write_char(c)?,
c => {
write!(out, "\\u{{{:x}}}", c as u32)?;
}
};
}
Ok(())
}
fn format_file(
tokens: &Tokens,
out: &mut fmt::Formatter<'_>,
config: &Self::Config,
) -> fmt::Result {
let mut imports = Tokens::new();
Self::imports(&mut imports, tokens);
let format = Format::default();
imports.format(out, config, &format)?;
tokens.format(out, config, &format)?;
Ok(())
}
}
Import(Import) {
fn format(&self, out: &mut fmt::Formatter<'_>, _: &Config, _: &Format) -> fmt::Result {
out.write_str(&self.name)
}
}
ImportImplementationOnly(ImportImplementationOnly) {
fn format(&self, out: &mut fmt::Formatter<'_>, _: &Config, _: &Format) -> fmt::Result {
out.write_str(&self.name)
}
}
}
#[derive(Debug, Default)]
pub struct Format {}
#[derive(Debug, Default)]
pub struct Config {}
#[derive(Debug, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct Import {
module: ItemStr,
name: ItemStr,
}
#[derive(Debug, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct ImportImplementationOnly {
module: ItemStr,
name: ItemStr,
}
#[derive(Debug, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
enum ImportType {
Import,
ImportImplementationOnly,
}
impl Swift {
fn imports(out: &mut Tokens, tokens: &Tokens) {
use crate as genco;
use crate::quote_in;
let mut modules = BTreeSet::new();
for import in tokens.iter_lang() {
match import.kind() {
AnyKind::Import(ref i) => {
modules.insert((&i.module, ImportType::Import));
}
AnyKind::ImportImplementationOnly(ref i) => {
modules.insert((&i.module, ImportType::ImportImplementationOnly));
}
}
}
if !modules.is_empty() {
for (module, import_type) in modules {
match import_type {
ImportType::Import => {
quote_in! { *out => $['\r']import $module}
}
ImportType::ImportImplementationOnly => {
quote_in! { *out => $['\r']@_implementationOnly import $module}
}
}
}
}
out.line();
}
}
pub fn import<M, N>(module: M, name: N) -> Import
where
M: Into<ItemStr>,
N: Into<ItemStr>,
{
Import {
module: module.into(),
name: name.into(),
}
}
pub fn import_implementation_only(
module: impl Into<ItemStr>,
name: impl Into<ItemStr>,
) -> ImportImplementationOnly {
ImportImplementationOnly {
module: module.into(),
name: name.into(),
}
}