notation_proto/
proto_entry.rs1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4
5use notation_core::prelude::{CoreEntry, Duration, Entry, EntryPassMode, MetaEntry};
6use notation_fretted::prelude::{FrettedEntry4, FrettedEntry6};
7
8use crate::prelude::LyricEntry;
9
10#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
11pub enum ProtoEntry {
12 Mark(String),
13 Meta(MetaEntry),
14 Core(CoreEntry),
15 Lyric(LyricEntry),
16 Fretted6(FrettedEntry6),
17 Fretted4(FrettedEntry4),
18 Extra(String, String),
19}
20impl Display for ProtoEntry {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 match self {
23 ProtoEntry::Mark(x) => write!(f, "Mark({})", x),
24 ProtoEntry::Meta(x) => write!(f, "Meta({})", x),
25 ProtoEntry::Core(x) => write!(f, "Core({})", x),
26 ProtoEntry::Lyric(x) => write!(f, "Lyric({})", x),
27 ProtoEntry::Fretted6(x) => write!(f, "Fretted6({})", x),
28 ProtoEntry::Fretted4(x) => write!(f, "Fretted4({})", x),
29 ProtoEntry::Extra(x, y) => write!(f, "Extra({}, {})", x, y),
30 }
31 }
32}
33impl ProtoEntry {
34 pub fn duration(&self) -> Duration {
35 match self {
36 ProtoEntry::Mark(_) => Duration::Zero,
37 ProtoEntry::Meta(entry) => entry.duration(),
38 ProtoEntry::Core(entry) => entry.duration(),
39 ProtoEntry::Lyric(entry) => entry.duration(),
40 ProtoEntry::Fretted6(entry) => entry.duration(),
41 ProtoEntry::Fretted4(entry) => entry.duration(),
42 ProtoEntry::Extra(_, _) => Duration::Zero,
43 }
44 }
45 pub fn pass_mode(&self) -> EntryPassMode {
46 match self {
47 ProtoEntry::Mark(_) => EntryPassMode::Immediate,
48 ProtoEntry::Meta(entry) => entry.pass_mode(),
49 ProtoEntry::Core(entry) => entry.pass_mode(),
50 ProtoEntry::Lyric(entry) => entry.pass_mode(),
51 ProtoEntry::Fretted6(entry) => entry.pass_mode(),
52 ProtoEntry::Fretted4(entry) => entry.pass_mode(),
53 ProtoEntry::Extra(_, _) => EntryPassMode::Immediate,
54 }
55 }
56 pub fn is_mark(&self) -> bool {
58 matches!(self, Self::Mark(..))
59 }
60 pub fn is_mark_string(&self, val: &String) -> bool {
61 if let Self::Mark(v) = self {
62 v == val
63 } else {
64 false
65 }
66 }
67 pub fn is_mark_str(&self, val: &str) -> bool {
68 if let Self::Mark(v) = self {
69 v.as_str() == val
70 } else {
71 false
72 }
73 }
74 pub fn is_meta(&self) -> bool {
76 matches!(self, Self::Meta(..))
77 }
78 pub fn is_core(&self) -> bool {
80 matches!(self, Self::Core(..))
81 }
82 pub fn is_word(&self) -> bool {
84 matches!(self, Self::Lyric(..))
85 }
86 pub fn as_mark(&self) -> Option<&String> {
87 if let Self::Mark(v) = self {
88 Some(v)
89 } else {
90 None
91 }
92 }
93 pub fn as_meta(&self) -> Option<&MetaEntry> {
94 if let Self::Meta(v) = self {
95 Some(v)
96 } else {
97 None
98 }
99 }
100 pub fn as_core(&self) -> Option<&CoreEntry> {
101 if let Self::Core(v) = self {
102 Some(v)
103 } else {
104 None
105 }
106 }
107 pub fn try_into_core(self) -> Result<CoreEntry, Self> {
108 if let Self::Core(v) = self {
109 Ok(v)
110 } else {
111 Err(self)
112 }
113 }
114 pub fn is_fretted6(&self) -> bool {
116 matches!(self, Self::Fretted6(..))
117 }
118 pub fn as_fretted6(&self) -> Option<&FrettedEntry6> {
119 if let Self::Fretted6(v) = self {
120 Some(v)
121 } else {
122 None
123 }
124 }
125 pub fn try_into_fretted6(self) -> Result<FrettedEntry6, Self> {
126 if let Self::Fretted6(v) = self {
127 Ok(v)
128 } else {
129 Err(self)
130 }
131 }
132 pub fn is_fretted4(&self) -> bool {
134 matches!(self, Self::Fretted4(..))
135 }
136 pub fn as_fretted4(&self) -> Option<&FrettedEntry4> {
137 if let Self::Fretted4(v) = self {
138 Some(v)
139 } else {
140 None
141 }
142 }
143 pub fn try_into_fretted4(self) -> Result<FrettedEntry4, Self> {
144 if let Self::Fretted4(v) = self {
145 Ok(v)
146 } else {
147 Err(self)
148 }
149 }
150}
151impl ProtoEntry {
152 pub const COMMENT_CHAR: char = ';';
153 pub fn is_core_tie(&self) -> bool {
154 self.as_core().map(|x| x.is_tie()).unwrap_or(false)
155 }
156 pub fn trim_comments(mark: &String) -> String {
157 if let Some(index) = mark.find(Self::COMMENT_CHAR) {
158 return mark[..index].to_string();
159 }
160 mark.clone()
161 }
162}
163impl Entry for ProtoEntry {
164 fn duration(&self) -> Duration {
165 self.duration()
166 }
167 fn pass_mode(&self) -> EntryPassMode {
168 self.pass_mode()
169 }
170}
171
172impl From<String> for ProtoEntry {
173 fn from(v: String) -> Self {
174 ProtoEntry::Mark(v)
175 }
176}
177
178impl From<&str> for ProtoEntry {
179 fn from(v: &str) -> Self {
180 ProtoEntry::Mark(String::from(v))
181 }
182}
183
184impl From<(String, String)> for ProtoEntry {
185 fn from(v: (String, String)) -> Self {
186 ProtoEntry::Extra(v.0, v.1)
187 }
188}
189
190impl From<(&str, String)> for ProtoEntry {
191 fn from(v: (&str, String)) -> Self {
192 ProtoEntry::Extra(String::from(v.0), v.1)
193 }
194}
195
196impl From<(String, &str)> for ProtoEntry {
197 fn from(v: (String, &str)) -> Self {
198 ProtoEntry::Extra(v.0, String::from(v.1))
199 }
200}
201
202impl From<(&str, &str)> for ProtoEntry {
203 fn from(v: (&str, &str)) -> Self {
204 ProtoEntry::Extra(String::from(v.0), String::from(v.1))
205 }
206}
207
208impl From<MetaEntry> for ProtoEntry {
209 fn from(v: MetaEntry) -> Self {
210 ProtoEntry::Meta(v)
211 }
212}
213
214impl From<CoreEntry> for ProtoEntry {
215 fn from(v: CoreEntry) -> Self {
216 ProtoEntry::Core(v)
217 }
218}
219
220impl From<LyricEntry> for ProtoEntry {
221 fn from(v: LyricEntry) -> Self {
222 ProtoEntry::Lyric(v)
223 }
224}
225
226impl From<FrettedEntry6> for ProtoEntry {
227 fn from(v: FrettedEntry6) -> Self {
228 ProtoEntry::Fretted6(v)
229 }
230}
231
232impl From<FrettedEntry4> for ProtoEntry {
233 fn from(v: FrettedEntry4) -> Self {
234 ProtoEntry::Fretted4(v)
235 }
236}