pub mod error;
pub mod types;
use std::fmt::Debug;
use std::num::{IntErrorKind, ParseIntError};
use std::path::PathBuf;
use crate::osu_file::types::Decimal;
use crate::parsers::comma;
use nom::bytes::complete::take_till;
use nom::combinator::map_res;
use nom::multi::separated_list0;
use nom::Finish;
use rust_decimal_macros::dec;
use crate::helper;
use crate::helper::macros::*;
use crate::osu_file::Integer;
pub use error::*;
pub use types::*;
versioned_field!(AudioFilename, PathBuf, no_versions, |s| { Ok(PathBuf::from(s)) } -> (), |v| { v.display().to_string() }, PathBuf::from(""));
versioned_field!(AudioLeadIn, Integer, no_versions, |s| { s.parse() } -> ParseIntError,, 0);
versioned_field!(AudioHash, String, no_versions, |s| { Ok(s.to_string()) } -> (),
|v, version| { if version > 13 { None } else { Some(v.to_string()) } },
|version| { if version > 13 { None } else { Some(String::new())}
});
versioned_field!(PreviewTime, Integer, no_versions, |s| { s.parse() } -> ParseIntError,, -1);
versioned_field!(StackLeniency, Decimal, no_versions, |s| { s.parse() } -> (),, Decimal::from(dec!(0.7)));
versioned_field!(LetterboxInBreaks, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, false);
versioned_field!(StoryFireInFront, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, true);
versioned_field!(UseSkinSprites, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, false);
versioned_field!(AlwaysShowPlayfield, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, false);
versioned_field!(SkinPreference, String, no_versions, |s| { Ok(s.to_string()) } -> (),, String::new());
versioned_field!(EpilepsyWarning, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, false);
versioned_field!(CountdownOffset, Integer, no_versions, |s| { s.parse() } -> ParseIntError,, 0);
versioned_field!(SpecialStyle, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, false);
versioned_field!(WidescreenStoryboard, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, false);
versioned_field!(SamplesMatchPlaybackRate, bool, no_versions, |s| { helper::parse_zero_one_bool(s) } -> helper::ParseZeroOneBoolError, boolean, false);
versioned_field!(EditorBookmarks, Vec<Integer>, no_versions, |s| {
let bookmark = map_res(take_till(|c| c == ','), |s: &str| s.parse::<Integer>());
let mut bookmarks = separated_list0(comma::<nom::error::Error<_>>(), bookmark);
let input_len = s.len();
let (s, bookmarks) = bookmarks(s).finish().unwrap();
if s.is_empty() {
Ok(bookmarks)
} else {
let (_, s) = {
let s = if s.len() < input_len {
match s.strip_prefix(',') {
Some(s) => s,
None => s,
}
} else {
s
};
take_till::<_, _, nom::error::Error<_>>(|c| c == ',')(s).unwrap()
};
let err = s.parse::<Integer>().unwrap_err();
let err = if let IntErrorKind::Empty = err.kind() {
ParseError::InvalidCommaList
} else {
ParseError::ParseIntError(err)
};
Err(err)
}
} -> ParseError,
|v, version| {
if version > 5 {
return None;
}
Some(v.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(","))
},
);
versioned_field!(EditorDistanceSpacing, Decimal, no_versions, |s| { s.parse() } -> (),
|v, version| {
if version > 5 {
return None;
}
Some(v.to_string())
}
,);
general_section!(
pub struct General {
pub audio_filename: AudioFilename,
pub audio_lead_in: AudioLeadIn,
pub audio_hash: AudioHash,
pub preview_time: PreviewTime,
pub countdown: Countdown,
pub sample_set: SampleSet,
pub stack_leniency: StackLeniency,
pub mode: Mode,
pub letterbox_in_breaks: LetterboxInBreaks,
pub story_fire_in_front: StoryFireInFront,
pub use_skin_sprites: UseSkinSprites,
pub always_show_playfield: AlwaysShowPlayfield,
pub overlay_position: OverlayPosition,
pub skin_preference: SkinPreference,
pub epilepsy_warning: EpilepsyWarning,
pub countdown_offset: CountdownOffset,
pub special_style: SpecialStyle,
pub widescreen_storyboard: WidescreenStoryboard,
pub samples_match_playback_rate: SamplesMatchPlaybackRate,
pub editor_bookmarks: EditorBookmarks,
pub editor_distance_spacing: EditorDistanceSpacing,
},
ParseError,
" ",
);