use crate::io::RenderKotlin;
use crate::spec::CodeBlock;
use crate::tokens;
#[derive(Debug, Clone)]
pub struct KDoc {
content: String,
}
impl KDoc {
pub fn new() -> KDoc {
KDoc {
content: String::new()
}
}
pub fn append(mut self, content: &str) -> KDoc {
self.content.push_str(content);
self
}
pub fn merge(mut self, other: KDoc) -> KDoc {
self.content.push_str(tokens::NEW_LINE);
self.content.push_str(other.content.as_str());
self
}
}
impl From<&str> for KDoc {
fn from(value: &str) -> Self {
KDoc::new().append(value)
}
}
impl RenderKotlin for KDoc {
fn render_into(&self, block: &mut CodeBlock) {
block.push_static_atom(tokens::KDOC_COMMENT_START);
block.push_new_line();
let split = self.content.split(tokens::NEW_LINE)
.enumerate().collect::<Vec<_>>();
let split_len = split.len();
for (idx, line) in split {
if idx == split_len - 1 && line.is_empty() {
break;
}
block.push_static_atom(tokens::KDOC_COMMENT_MIDDLE);
block.push_space();
block.push_atom(line);
block.push_new_line();
}
block.push_static_atom(tokens::KDOC_COMMENT_END);
}
}
#[derive(Default, Clone, Debug)]
pub(crate) struct KdocSlot(Option<KDoc>);
impl RenderKotlin for KdocSlot {
fn render_into(&self, block: &mut CodeBlock) {
if let Some(kdoc) = &self.0 {
block.push_renderable(kdoc);
block.push_new_line()
}
}
}
impl KdocSlot {
pub(crate) fn merge(&mut self, other: KDoc) {
match self.0 {
None => { self.0 = Some(other) }
Some(ref mut old) => {
old.content.push_str(tokens::NEW_LINE);
old.content.push_str(other.content.as_str());
}
};
}
}
macro_rules! mixin_kdoc_mutators {
() => {
pub fn kdoc<KDocLike: Into<crate::spec::KDoc>> (mut self, kdoc: KDocLike) -> Self {
self.kdoc.merge(kdoc.into());
self
}
};
}
pub(crate) use mixin_kdoc_mutators;
#[cfg(test)]
mod tests {
use crate::io::RenderKotlin;
#[test]
fn test_kdoc_render() {
let comment = super::KDoc::new()
.append("Hello\n")
.append("World\n");
assert_eq!(
comment.render_string(),
"/**\n * Hello\n * World\n */"
)
}
#[test]
fn test_comment_block() {
let comment = super::KDoc::new()
.append("Hello\n")
.merge(super::KDoc::new().append("World\n"));
assert_eq!(
comment.render_string(),
"/**\n * Hello\n * \n * World\n */"
)
}
}