use std::path::Path;
use super::{ProcessContext, TokenProcessor};
use crate::bms::ParseErrorWithRange;
use crate::bms::{model::music_info::MusicInfo, prelude::*};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MusicInfoProcessor;
impl TokenProcessor for MusicInfoProcessor {
type Output = MusicInfo;
fn process<P: Prompter>(
&self,
ctx: &mut ProcessContext<'_, '_, P>,
) -> core::result::Result<Self::Output, ParseErrorWithRange> {
let mut music_info = MusicInfo::default();
ctx.all_tokens(|token, _prompter| match token.content() {
Token::Header { name, args } => {
self.on_header(name.as_ref(), args.as_ref(), &mut music_info);
Ok(None)
}
Token::Message { .. } | Token::NotACommand(_) => Ok(None),
})?;
Ok(music_info)
}
}
impl MusicInfoProcessor {
fn on_header(self, name: &str, args: &str, music_info: &mut MusicInfo) {
if name.eq_ignore_ascii_case("GENRE") {
music_info.genre = Some(args.to_string());
}
if name.eq_ignore_ascii_case("TITLE") {
music_info.title = Some(args.to_string());
}
if name.eq_ignore_ascii_case("SUBTITLE") {
music_info.subtitle = Some(args.to_string());
}
if name.eq_ignore_ascii_case("ARTIST") {
music_info.artist = Some(args.to_string());
}
if name.eq_ignore_ascii_case("SUBARTIST") {
music_info.sub_artist = Some(args.to_string());
}
if name.eq_ignore_ascii_case("COMMENT") {
music_info
.comment
.get_or_insert_with(Vec::new)
.push(args.to_string());
}
if name.eq_ignore_ascii_case("MAKER") {
music_info.maker = Some(args.to_string());
}
if name.eq_ignore_ascii_case("PREVIEW") {
music_info.preview_music = Some(Path::new(args).into());
}
}
}