vimwiki_core/lang/elements/blocks/
code.rs1use crate::StrictEq;
2use derive_more::{Constructor, Index, IndexMut, IntoIterator};
3use serde::{Deserialize, Serialize};
4use std::{borrow::Cow, collections::HashMap, iter::FromIterator};
5
6#[derive(
7 Constructor,
8 Clone,
9 Debug,
10 Eq,
11 PartialEq,
12 Index,
13 IndexMut,
14 IntoIterator,
15 Serialize,
16 Deserialize,
17)]
18pub struct CodeBlock<'a> {
19 pub language: Option<Cow<'a, str>>,
21
22 pub metadata: HashMap<Cow<'a, str>, Cow<'a, str>>,
25
26 #[index]
28 #[index_mut]
29 #[into_iterator(owned, ref, ref_mut)]
30 pub lines: Vec<Cow<'a, str>>,
31}
32
33impl<'a> CodeBlock<'a> {
34 pub fn from_lines<I: IntoIterator<Item = L>, L: Into<Cow<'a, str>>>(
36 iter: I,
37 ) -> Self {
38 Self {
39 language: None,
40 metadata: HashMap::new(),
41 lines: iter.into_iter().map(Into::into).collect(),
42 }
43 }
44}
45
46impl CodeBlock<'_> {
47 pub fn to_borrowed(&self) -> CodeBlock {
48 use self::Cow::*;
49
50 CodeBlock {
51 language: self.language.as_ref().map(|x| {
52 Cow::Borrowed(match x {
53 Borrowed(x) => *x,
54 Owned(x) => x.as_str(),
55 })
56 }),
57 metadata: self
58 .metadata
59 .iter()
60 .map(|(key, value)| {
61 let key = Cow::Borrowed(match key {
62 Borrowed(x) => *x,
63 Owned(x) => x.as_str(),
64 });
65 let value = Cow::Borrowed(match value {
66 Borrowed(x) => *x,
67 Owned(x) => x.as_str(),
68 });
69
70 (key, value)
71 })
72 .collect(),
73 lines: self
74 .lines
75 .iter()
76 .map(|x| {
77 Cow::Borrowed(match x {
78 Borrowed(x) => *x,
79 Owned(x) => x.as_str(),
80 })
81 })
82 .collect(),
83 }
84 }
85
86 pub fn into_owned(self) -> CodeBlock<'static> {
87 CodeBlock {
88 language: self.language.map(|x| Cow::from(x.into_owned())),
89 metadata: self
90 .metadata
91 .into_iter()
92 .map(|(key, value)| {
93 (Cow::from(key.into_owned()), Cow::from(value.into_owned()))
94 })
95 .collect(),
96 lines: self
97 .lines
98 .into_iter()
99 .map(|x| Cow::from(x.into_owned()))
100 .collect(),
101 }
102 }
103}
104
105impl<'a> FromIterator<&'a str> for CodeBlock<'a> {
106 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
109 Self::from_lines(iter)
110 }
111}
112
113impl FromIterator<String> for CodeBlock<'static> {
114 fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> Self {
117 Self::from_lines(iter)
118 }
119}
120
121impl<'a> FromIterator<Cow<'a, str>> for CodeBlock<'a> {
122 fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> Self {
125 Self::from_lines(iter)
126 }
127}
128
129impl<'a> StrictEq for CodeBlock<'a> {
130 fn strict_eq(&self, other: &Self) -> bool {
132 self == other
133 }
134}