added async_tokio feature
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
## Upcoming
|
## Upcoming
|
||||||
|
|
||||||
|
- Async beatmap parsing
|
||||||
|
|
||||||
# v0.1.1
|
# v0.1.1
|
||||||
|
|
||||||
- parse:
|
- parse:
|
||||||
|
|||||||
+20
-5
@@ -8,20 +8,35 @@ readme = "README.md"
|
|||||||
repository = "https://github.com/MaxOhn/rosu-pp"
|
repository = "https://github.com/MaxOhn/rosu-pp"
|
||||||
documentation = "https://docs.rs/rosu-pp/"
|
documentation = "https://docs.rs/rosu-pp/"
|
||||||
description = "osu! difficulty and pp calculation for all modes"
|
description = "osu! difficulty and pp calculation for all modes"
|
||||||
keywords = ["osu", "pp", "stars", "async", "async-std"]
|
keywords = ["osu", "pp", "stars", "async"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["osu", "taiko", "fruits", "mania", "no_leniency", "async_std"]
|
default = ["osu", "taiko", "fruits", "mania", "no_leniency"]
|
||||||
|
|
||||||
|
# game modes
|
||||||
osu = []
|
osu = []
|
||||||
taiko = []
|
taiko = []
|
||||||
fruits = []
|
fruits = []
|
||||||
mania = []
|
mania = []
|
||||||
|
|
||||||
|
# osu!standard version
|
||||||
all_included = []
|
all_included = []
|
||||||
no_leniency = []
|
no_leniency = []
|
||||||
no_sliders_no_leniency = []
|
no_sliders_no_leniency = []
|
||||||
async_std = ["async-std"]
|
|
||||||
|
|
||||||
[dependencies]
|
# async version
|
||||||
async-std = { version = "1.9.0", optional = true }
|
async_std = ["async-std"]
|
||||||
|
async_tokio = ["tokio"]
|
||||||
|
|
||||||
|
[dependencies.async-std]
|
||||||
|
version = "1.9"
|
||||||
|
optional = true
|
||||||
|
|
||||||
|
[dependencies.tokio]
|
||||||
|
version = "1.2"
|
||||||
|
optional = true
|
||||||
|
default-features = false
|
||||||
|
features = ["io-util"]
|
||||||
|
|
||||||
|
[dev-dependencies.tokio]
|
||||||
|
features = ["fs", "rt-multi-thread"]
|
||||||
+840
-332
File diff suppressed because it is too large
Load Diff
+65
-63
@@ -3,7 +3,6 @@
|
|||||||
extern crate rosu_pp;
|
extern crate rosu_pp;
|
||||||
|
|
||||||
use rosu_pp::Beatmap;
|
use rosu_pp::Beatmap;
|
||||||
use std::fs::File;
|
|
||||||
|
|
||||||
struct MapResult {
|
struct MapResult {
|
||||||
map_id: u32,
|
map_id: u32,
|
||||||
@@ -12,8 +11,28 @@ struct MapResult {
|
|||||||
pp: f32,
|
pp: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_result {
|
||||||
|
($kind:expr => $result:expr, $margin:expr, $expected:ident, $map_id:ident, $mods:ident) => {
|
||||||
|
assert!(
|
||||||
|
($result - $expected).abs() < $margin * $expected,
|
||||||
|
"\n{kind}:\n\
|
||||||
|
Calculated: {calculated} | Expected: {expected}\n \
|
||||||
|
=> {margin} margin ({allowed} allowed)\n\
|
||||||
|
[map {map} | mods {mods}]\n",
|
||||||
|
kind = $kind,
|
||||||
|
calculated = $result,
|
||||||
|
expected = $expected,
|
||||||
|
margin = ($result - $expected).abs(),
|
||||||
|
allowed = $margin * $expected,
|
||||||
|
map = $map_id,
|
||||||
|
mods = $mods
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "async_std", feature = "async_tokio")))]
|
||||||
#[test]
|
#[test]
|
||||||
fn fruits() {
|
fn fruits_sync() {
|
||||||
let star_margin = 0.0001;
|
let star_margin = 0.0001;
|
||||||
let pp_margin = 0.0001;
|
let pp_margin = 0.0001;
|
||||||
|
|
||||||
@@ -25,7 +44,7 @@ fn fruits() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)) {
|
let file = match std::fs::File::open(format!("./maps/{}.osu", map_id)) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
@@ -37,42 +56,50 @@ fn fruits() {
|
|||||||
|
|
||||||
let result = rosu_pp::FruitsPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::FruitsPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async_tokio")]
|
||||||
|
#[test]
|
||||||
|
fn fruits_async_tokio() {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.expect("could not start runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let star_margin = 0.0001;
|
||||||
|
let pp_margin = 0.0001;
|
||||||
|
|
||||||
|
for result in RESULTS {
|
||||||
|
let MapResult {
|
||||||
|
map_id,
|
||||||
|
mods,
|
||||||
|
stars,
|
||||||
|
pp,
|
||||||
|
} = result;
|
||||||
|
|
||||||
|
let file = match tokio::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let map = match Beatmap::parse(file).await {
|
||||||
|
Ok(map) => map,
|
||||||
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = rosu_pp::FruitsPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async_std")]
|
#[cfg(feature = "async_std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn fruits_async() {
|
fn fruits_async_std() {
|
||||||
use async_std::{fs::File, task};
|
async_std::task::block_on(async {
|
||||||
|
|
||||||
task::block_on(async {
|
|
||||||
let star_margin = 0.0001;
|
let star_margin = 0.0001;
|
||||||
let pp_margin = 0.0001;
|
let pp_margin = 0.0001;
|
||||||
|
|
||||||
@@ -84,45 +111,20 @@ fn fruits_async() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)).await {
|
let file = match async_std::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let map = match Beatmap::parse_async(file).await {
|
let map = match Beatmap::parse(file).await {
|
||||||
Ok(map) => map,
|
Ok(map) => map,
|
||||||
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = rosu_pp::FruitsPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::FruitsPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-63
@@ -3,7 +3,6 @@
|
|||||||
extern crate rosu_pp;
|
extern crate rosu_pp;
|
||||||
|
|
||||||
use rosu_pp::Beatmap;
|
use rosu_pp::Beatmap;
|
||||||
use std::fs::File;
|
|
||||||
|
|
||||||
struct MapResult {
|
struct MapResult {
|
||||||
map_id: u32,
|
map_id: u32,
|
||||||
@@ -12,8 +11,28 @@ struct MapResult {
|
|||||||
pp: f32,
|
pp: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_result {
|
||||||
|
($kind:expr => $result:expr, $margin:expr, $expected:ident, $map_id:ident, $mods:ident) => {
|
||||||
|
assert!(
|
||||||
|
($result - $expected).abs() < $margin * $expected,
|
||||||
|
"\n{kind}:\n\
|
||||||
|
Calculated: {calculated} | Expected: {expected}\n \
|
||||||
|
=> {margin} margin ({allowed} allowed)\n\
|
||||||
|
[map {map} | mods {mods}]\n",
|
||||||
|
kind = $kind,
|
||||||
|
calculated = $result,
|
||||||
|
expected = $expected,
|
||||||
|
margin = ($result - $expected).abs(),
|
||||||
|
allowed = $margin * $expected,
|
||||||
|
map = $map_id,
|
||||||
|
mods = $mods
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "async_std", feature = "async_tokio")))]
|
||||||
#[test]
|
#[test]
|
||||||
fn mania() {
|
fn mania_sync() {
|
||||||
let star_margin = 0.00001;
|
let star_margin = 0.00001;
|
||||||
let pp_margin = 0.00001;
|
let pp_margin = 0.00001;
|
||||||
|
|
||||||
@@ -25,7 +44,7 @@ fn mania() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)) {
|
let file = match std::fs::File::open(format!("./maps/{}.osu", map_id)) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
@@ -37,42 +56,50 @@ fn mania() {
|
|||||||
|
|
||||||
let result = rosu_pp::ManiaPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::ManiaPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async_tokio")]
|
||||||
|
#[test]
|
||||||
|
fn mania_async_tokio() {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.expect("could not start runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let star_margin = 0.00001;
|
||||||
|
let pp_margin = 0.00001;
|
||||||
|
|
||||||
|
for result in RESULTS {
|
||||||
|
let MapResult {
|
||||||
|
map_id,
|
||||||
|
mods,
|
||||||
|
stars,
|
||||||
|
pp,
|
||||||
|
} = result;
|
||||||
|
|
||||||
|
let file = match tokio::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let map = match Beatmap::parse(file).await {
|
||||||
|
Ok(map) => map,
|
||||||
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = rosu_pp::ManiaPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async_std")]
|
#[cfg(feature = "async_std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn mania_async() {
|
fn mania_async_std() {
|
||||||
use async_std::{fs::File, task};
|
async_std::task::block_on(async {
|
||||||
|
|
||||||
task::block_on(async {
|
|
||||||
let star_margin = 0.00001;
|
let star_margin = 0.00001;
|
||||||
let pp_margin = 0.00001;
|
let pp_margin = 0.00001;
|
||||||
|
|
||||||
@@ -84,45 +111,20 @@ fn mania_async() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)).await {
|
let file = match async_std::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let map = match Beatmap::parse_async(file).await {
|
let map = match Beatmap::parse(file).await {
|
||||||
Ok(map) => map,
|
Ok(map) => map,
|
||||||
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = rosu_pp::ManiaPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::ManiaPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+75
-75
@@ -3,7 +3,6 @@
|
|||||||
extern crate rosu_pp;
|
extern crate rosu_pp;
|
||||||
|
|
||||||
use rosu_pp::Beatmap;
|
use rosu_pp::Beatmap;
|
||||||
use std::fs::File;
|
|
||||||
|
|
||||||
struct MapResult {
|
struct MapResult {
|
||||||
map_id: u32,
|
map_id: u32,
|
||||||
@@ -12,9 +11,27 @@ struct MapResult {
|
|||||||
pp: f32,
|
pp: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
macro_rules! assert_result {
|
||||||
fn osu() {
|
($kind:expr => $result:expr, $margin:expr, $expected:ident, $map_id:ident, $mods:ident) => {
|
||||||
let margin = if cfg!(feature = "no_sliders_no_leniency") {
|
assert!(
|
||||||
|
($result - $expected).abs() < $margin * $expected,
|
||||||
|
"\n{kind}:\n\
|
||||||
|
Calculated: {calculated} | Expected: {expected}\n \
|
||||||
|
=> {margin} margin ({allowed} allowed)\n\
|
||||||
|
[map {map} | mods {mods}]\n",
|
||||||
|
kind = $kind,
|
||||||
|
calculated = $result,
|
||||||
|
expected = $expected,
|
||||||
|
margin = ($result - $expected).abs(),
|
||||||
|
allowed = $margin * $expected,
|
||||||
|
map = $map_id,
|
||||||
|
mods = $mods
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn margin() -> f32 {
|
||||||
|
if cfg!(feature = "no_sliders_no_leniency") {
|
||||||
0.0075
|
0.0075
|
||||||
} else if cfg!(feature = "no_leniency") {
|
} else if cfg!(feature = "no_leniency") {
|
||||||
0.0025
|
0.0025
|
||||||
@@ -22,7 +39,13 @@ fn osu() {
|
|||||||
0.001
|
0.001
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "async_std", feature = "async_tokio")))]
|
||||||
|
#[test]
|
||||||
|
fn osu_sync() {
|
||||||
|
let margin = margin();
|
||||||
|
|
||||||
let star_margin = margin;
|
let star_margin = margin;
|
||||||
let pp_margin = margin;
|
let pp_margin = margin;
|
||||||
@@ -35,7 +58,7 @@ fn osu() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)) {
|
let file = match std::fs::File::open(format!("./maps/{}.osu", map_id)) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
@@ -47,51 +70,53 @@ fn osu() {
|
|||||||
|
|
||||||
let result = rosu_pp::OsuPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::OsuPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async_tokio")]
|
||||||
|
#[test]
|
||||||
|
fn osu_async_tokio() {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.expect("could not start runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let margin = margin();
|
||||||
|
|
||||||
|
let star_margin = margin;
|
||||||
|
let pp_margin = margin;
|
||||||
|
|
||||||
|
for result in RESULTS {
|
||||||
|
let MapResult {
|
||||||
|
map_id,
|
||||||
|
mods,
|
||||||
|
stars,
|
||||||
|
pp,
|
||||||
|
} = result;
|
||||||
|
|
||||||
|
let file = match tokio::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let map = match Beatmap::parse(file).await {
|
||||||
|
Ok(map) => map,
|
||||||
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = rosu_pp::OsuPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async_std")]
|
#[cfg(feature = "async_std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn osu_async() {
|
fn osu_async_std() {
|
||||||
use async_std::{fs::File, task};
|
async_std::task::block_on(async {
|
||||||
|
let margin = margin();
|
||||||
task::block_on(async {
|
|
||||||
let margin = if cfg!(feature = "no_sliders_no_leniency") {
|
|
||||||
0.0075
|
|
||||||
} else if cfg!(feature = "no_leniency") {
|
|
||||||
0.0025
|
|
||||||
} else if cfg!(feature = "all_included") {
|
|
||||||
0.001
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
let star_margin = margin;
|
let star_margin = margin;
|
||||||
let pp_margin = margin;
|
let pp_margin = margin;
|
||||||
@@ -104,45 +129,20 @@ fn osu_async() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)).await {
|
let file = match async_std::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let map = match Beatmap::parse_async(file).await {
|
let map = match Beatmap::parse(file).await {
|
||||||
Ok(map) => map,
|
Ok(map) => map,
|
||||||
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = rosu_pp::OsuPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::OsuPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-63
@@ -3,7 +3,6 @@
|
|||||||
extern crate rosu_pp;
|
extern crate rosu_pp;
|
||||||
|
|
||||||
use rosu_pp::Beatmap;
|
use rosu_pp::Beatmap;
|
||||||
use std::fs::File;
|
|
||||||
|
|
||||||
struct MapResult {
|
struct MapResult {
|
||||||
map_id: u32,
|
map_id: u32,
|
||||||
@@ -12,8 +11,28 @@ struct MapResult {
|
|||||||
pp: f32,
|
pp: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! assert_result {
|
||||||
|
($kind:expr => $result:expr, $margin:expr, $expected:ident, $map_id:ident, $mods:ident) => {
|
||||||
|
assert!(
|
||||||
|
($result - $expected).abs() < $margin * $expected,
|
||||||
|
"\n{kind}:\n\
|
||||||
|
Calculated: {calculated} | Expected: {expected}\n \
|
||||||
|
=> {margin} margin ({allowed} allowed)\n\
|
||||||
|
[map {map} | mods {mods}]\n",
|
||||||
|
kind = $kind,
|
||||||
|
calculated = $result,
|
||||||
|
expected = $expected,
|
||||||
|
margin = ($result - $expected).abs(),
|
||||||
|
allowed = $margin * $expected,
|
||||||
|
map = $map_id,
|
||||||
|
mods = $mods
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "async_std", feature = "async_tokio")))]
|
||||||
#[test]
|
#[test]
|
||||||
fn taiko() {
|
fn taiko_sync() {
|
||||||
let star_margin = 0.0001;
|
let star_margin = 0.0001;
|
||||||
let pp_margin = 0.0001;
|
let pp_margin = 0.0001;
|
||||||
|
|
||||||
@@ -25,7 +44,7 @@ fn taiko() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)) {
|
let file = match std::fs::File::open(format!("./maps/{}.osu", map_id)) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
@@ -37,42 +56,50 @@ fn taiko() {
|
|||||||
|
|
||||||
let result = rosu_pp::TaikoPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::TaikoPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async_tokio")]
|
||||||
|
#[test]
|
||||||
|
fn taiko_async_tokio() {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.expect("could not start runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let star_margin = 0.0001;
|
||||||
|
let pp_margin = 0.0001;
|
||||||
|
|
||||||
|
for result in RESULTS {
|
||||||
|
let MapResult {
|
||||||
|
map_id,
|
||||||
|
mods,
|
||||||
|
stars,
|
||||||
|
pp,
|
||||||
|
} = result;
|
||||||
|
|
||||||
|
let file = match tokio::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let map = match Beatmap::parse(file).await {
|
||||||
|
Ok(map) => map,
|
||||||
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = rosu_pp::TaikoPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async_std")]
|
#[cfg(feature = "async_std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn taiko_async() {
|
fn taiko_async_std() {
|
||||||
use async_std::{fs::File, task};
|
async_std::task::block_on(async {
|
||||||
|
|
||||||
task::block_on(async {
|
|
||||||
let star_margin = 0.0001;
|
let star_margin = 0.0001;
|
||||||
let pp_margin = 0.0001;
|
let pp_margin = 0.0001;
|
||||||
|
|
||||||
@@ -84,45 +111,20 @@ fn taiko_async() {
|
|||||||
pp,
|
pp,
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
let file = match File::open(format!("./maps/{}.osu", map_id)).await {
|
let file = match async_std::fs::File::open(format!("./maps/{}.osu", map_id)).await {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
Err(why) => panic!("Could not open file {}.osu: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let map = match Beatmap::parse_async(file).await {
|
let map = match Beatmap::parse(file).await {
|
||||||
Ok(map) => map,
|
Ok(map) => map,
|
||||||
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
Err(why) => panic!("Error while parsing map {}: {}", map_id, why),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = rosu_pp::TaikoPP::new(&map).mods(*mods).calculate();
|
let result = rosu_pp::TaikoPP::new(&map).mods(*mods).calculate();
|
||||||
|
|
||||||
assert!(
|
assert_result!("Stars" => result.stars(), star_margin, stars, map_id, mods);
|
||||||
(result.stars() - stars).abs() < star_margin * stars,
|
assert_result!("PP" => result.pp(), pp_margin, pp, map_id, mods);
|
||||||
"\nStars:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.stars(),
|
|
||||||
expected = stars,
|
|
||||||
margin = (result.stars() - stars).abs(),
|
|
||||||
allowed = star_margin * stars,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
(result.pp() - pp).abs() < pp_margin * pp,
|
|
||||||
"\nPP:\n\
|
|
||||||
Calculated: {calculated} | Expected: {expected}\n \
|
|
||||||
=> {margin} margin ({allowed} allowed)\n\
|
|
||||||
[map {map} | mods {mods}]\n",
|
|
||||||
calculated = result.pp(),
|
|
||||||
expected = pp,
|
|
||||||
margin = (result.pp() - pp).abs(),
|
|
||||||
allowed = pp_margin * pp,
|
|
||||||
map = map_id,
|
|
||||||
mods = mods
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user