From 41cb73445787f68554340fee493f121567298d81 Mon Sep 17 00:00:00 2001 From: "Gustavo \"Guz\" L. de Mello" Date: Wed, 24 Apr 2024 20:27:06 -0300 Subject: [PATCH] refactor: improve Post's api for the conversion --- src/convert/npf.rs | 93 +++++++++++-------------------- src/convert/npf/content_blocks.rs | 11 ++++ src/convert/npf/objects_post.rs | 54 ++++++++++++++++++ 3 files changed, 98 insertions(+), 60 deletions(-) diff --git a/src/convert/npf.rs b/src/convert/npf.rs index 49fad19..a8cfa54 100644 --- a/src/convert/npf.rs +++ b/src/convert/npf.rs @@ -1,6 +1,7 @@ use std::{ borrow::{Borrow, BorrowMut}, cell::RefCell, + collections::VecDeque, }; use comrak::{ @@ -15,9 +16,12 @@ pub mod objects; pub mod text_formatting; mod objects_post; + use content_blocks::{BlockText, BlockValue}; use text_formatting::{FormatTypeBold, FormatTypeItalic, FormatValue}; +use self::content_blocks::BlockImage; + #[derive(Debug)] pub enum NPFConvertError { TODO, @@ -55,72 +59,41 @@ impl<'a> TryFrom<&'a Node<'a, RefCell>> for objects::Post { Ok(()) } NodeValue::Strong => { - let mut content = Self::try_from(n)?.content; - let mut res = content.iter_mut().fold( - BlockText::new(&String::new()), - |mut acc, c| match c { - BlockValue::Text(t) => { - let text = &t.text.trim(); - if let Some(ref mut f) = &mut t.formatting { - let offset = acc.text.chars().count() as u64; - f.iter_mut().for_each(|f| { - f.offset(offset); - }); - if let Some(ref mut af) = acc.formatting { - af.append(f); - } else { - acc.formatting = Some(f.to_vec()); - } + let mut content = Self::try_from(n)? + .fold_content() + .for_each_content(|c| { + if let BlockValue::Text(ref mut t) = c { + let format = FormatValue::Bold(FormatTypeBold::from(&t.text)); + if let Some(ref mut f) = t.formatting { + f.push(format); + } else { + t.formatting = Some(vec![format]); } - acc.text.push_str(&format!("{} ", text)); - acc + t.text = String::from(t.text.trim()); } - _ => acc, - }, - ); - res.text = res.text.trim().to_string(); - let format = FormatValue::Bold(FormatTypeBold::from(&res.text)); - if let Some(ref mut f) = res.formatting { - f.push(format); - } else { - res.formatting = Some(vec![format]); - } - post.content.push(BlockValue::Text(res)); + }) + .content; + post.content.append(&mut content); Ok(()) } NodeValue::Emph => { - let mut content = Self::try_from(n)?.content; - let mut res = content.iter_mut().fold( - BlockText::new(&String::new()), - |mut acc, c| match c { - BlockValue::Text(t) => { - let text = &t.text.trim(); - if let Some(ref mut f) = &mut t.formatting { - let offset = acc.text.chars().count() as u64; - f.iter_mut().for_each(|f| { - f.offset(offset); - }); - if let Some(ref mut af) = acc.formatting { - af.append(f); - } else { - acc.formatting = Some(f.to_vec()); - } + let mut content = Self::try_from(n)? + .fold_content() + .for_each_content(|c| { + if let BlockValue::Text(ref mut t) = c { + let format = FormatValue::Italic(FormatTypeItalic::from(&t.text)); + if let Some(ref mut f) = t.formatting { + f.push(format); + } else { + t.formatting = Some(vec![format]); } - acc.text.push_str(&format!("{} ", text)); - acc + t.text = String::from(t.text.trim()); } - _ => acc, - }, - ); - res.text = res.text.trim().to_string(); - let format = FormatValue::Italic(FormatTypeItalic::from(&res.text)); - if let Some(ref mut f) = res.formatting { - f.push(format); - } else { - res.formatting = Some(vec![format]); - } - // println!("italic {:#?}", res); - post.content.push(BlockValue::Text(res)); + }) + .content; + post.content.append(&mut content); + // println!("{:#?}", post); + Ok(()) } _ => Ok(()), @@ -129,7 +102,7 @@ impl<'a> TryFrom<&'a Node<'a, RefCell>> for objects::Post { if let Err(e) = r { Err(e) } else { - // println!("{:#?}", post); + println!("{:#?}", post); Ok(post) } } diff --git a/src/convert/npf/content_blocks.rs b/src/convert/npf/content_blocks.rs index 46e2a37..f927511 100644 --- a/src/convert/npf/content_blocks.rs +++ b/src/convert/npf/content_blocks.rs @@ -13,6 +13,17 @@ pub enum BlockValue { Audio(BlockAudio), Video(BlockVideo), } +impl BlockValue { + pub fn get_type(&self) -> String { + String::from(match &self { + BlockValue::Text(_) => "text", + BlockValue::Image(_) => "image", + BlockValue::Link(_) => "link", + BlockValue::Audio(_) => "audio", + BlockValue::Video(_) => "video", + }) + } +} #[derive(Debug, Deserialize, Serialize, Clone)] #[serde(rename_all = "snake_case")] diff --git a/src/convert/npf/objects_post.rs b/src/convert/npf/objects_post.rs index 0964d89..8363e53 100644 --- a/src/convert/npf/objects_post.rs +++ b/src/convert/npf/objects_post.rs @@ -1,4 +1,8 @@ +use itertools::Itertools; use serde::{Deserialize, Serialize}; + +use super::content_blocks::{BlockText, BlockValue}; + #[serde_with::skip_serializing_none] #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Post { @@ -56,6 +60,37 @@ impl Post { false } } + pub fn fold_content(mut self) -> Self { + // TODO: Some form of folding also the layout of the npf + let groups = self.content.iter_mut().group_by(|c| c.get_type() == "text"); + self.content = groups + .into_iter() + .map(|a| { + if a.0 == true { + vec![BlockValue::Text( + a.1.fold(BlockText::new(&String::new()), fold_text_block), + )] + } else { + a.1.map(|c| c.to_owned()).collect::>() + } + }) + .flatten() + .map(|mut a| { + if let BlockValue::Text(ref mut t) = a { + t.text = String::from(t.text.trim()); + } + a + }) + .collect::>(); + self + } + pub fn for_each_content(mut self, f: F) -> Self + where + F: Fn(&mut BlockValue), + { + self.content.iter_mut().for_each(f); + self + } fn default() -> Self { Self { object_type: String::from("post"), @@ -114,3 +149,22 @@ impl From for Post { } } +fn fold_text_block(mut acc: BlockText, c: &mut BlockValue) -> BlockText { + if let BlockValue::Text(t) = c { + let text = &t.text.trim(); + + if let Some(ref mut f) = &mut t.formatting { + let offset = acc.text.chars().count() as u64; + f.iter_mut().for_each(|f| f.offset(offset)); + + if let Some(ref mut af) = acc.formatting { + af.append(f); + } else { + acc.formatting = Some(f.to_vec()); + } + } + + acc.text.push_str(&format!("{} ", text)); + } + acc +}