|
|
@ -1,26 +1,103 @@ |
|
|
|
use crate::core::Core; |
|
|
|
use crate::{RawCode, ShortCode, CommonCode}; |
|
|
|
|
|
|
|
#[derive(Debug)] |
|
|
|
pub struct AllCases {} |
|
|
|
|
|
|
|
lazy_static! { |
|
|
|
static ref ALL_CASES: Vec<u64> = build_all_cases(); |
|
|
|
static ref BASIC_RANGES: Vec<u32> = build_basic_ranges(); |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn all_cases_fetch() -> &'static Vec<u64> { |
|
|
|
&(*ALL_CASES) |
|
|
|
static ref ALL_RAW_CODES: Vec<RawCode> = { |
|
|
|
build_all_cases().iter() |
|
|
|
.map(|code| CommonCode::new(*code).to_raw_code()) |
|
|
|
.collect() |
|
|
|
}; |
|
|
|
|
|
|
|
static ref ALL_COMMON_CODES: Vec<CommonCode> = { |
|
|
|
build_all_cases().iter() |
|
|
|
.map(|code| CommonCode::new(*code)) |
|
|
|
.collect() |
|
|
|
}; |
|
|
|
|
|
|
|
static ref ALL_SHORT_CODES: Vec<ShortCode> = { |
|
|
|
ShortCode::warm_up_fast(); |
|
|
|
build_all_cases().iter() |
|
|
|
.map(|code| CommonCode::new(*code).to_short_code()) |
|
|
|
.collect() |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
#[allow(dead_code)] |
|
|
|
pub fn basic_ranges_fetch() -> &'static Vec<u32> { |
|
|
|
&(*BASIC_RANGES) |
|
|
|
impl AllCases { |
|
|
|
/// Get all possible layouts and return an vector loaded with raw
|
|
|
|
/// `u64` common code.
|
|
|
|
#[inline] |
|
|
|
#[allow(dead_code)] |
|
|
|
pub(crate) fn all_cases() -> &'static Vec<u64> { |
|
|
|
&(*ALL_CASES) |
|
|
|
} |
|
|
|
|
|
|
|
/// Get all possible base ranges with `u32` value.
|
|
|
|
#[inline] |
|
|
|
#[allow(dead_code)] |
|
|
|
pub(crate) fn basic_ranges() -> &'static Vec<u32> { |
|
|
|
&(*BASIC_RANGES) |
|
|
|
} |
|
|
|
|
|
|
|
/// Get all possible layouts and return an vector loaded with RawCode.
|
|
|
|
/// # Example
|
|
|
|
/// ```
|
|
|
|
/// use klotski_ffi::AllCases;
|
|
|
|
///
|
|
|
|
/// let all_raw_codes = AllCases::raw_codes();
|
|
|
|
///
|
|
|
|
/// for raw_code in &all_raw_codes[..16] {
|
|
|
|
/// println!("{}", raw_code);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
#[inline] |
|
|
|
pub fn raw_codes() -> &'static Vec<RawCode> { |
|
|
|
&(*ALL_RAW_CODES) |
|
|
|
} |
|
|
|
|
|
|
|
/// Get all possible layouts and return an vector loaded with ShortCode.
|
|
|
|
/// # Example
|
|
|
|
/// ```
|
|
|
|
/// use klotski_ffi::AllCases;
|
|
|
|
///
|
|
|
|
/// let all_short_codes = AllCases::short_codes();
|
|
|
|
///
|
|
|
|
/// for short_code in &all_short_codes[..16] {
|
|
|
|
/// println!("{}", short_code);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
#[inline] |
|
|
|
pub fn short_codes() -> &'static Vec<ShortCode> { |
|
|
|
&(*ALL_SHORT_CODES) |
|
|
|
} |
|
|
|
|
|
|
|
/// Get all possible layouts and return an vector loaded with CommonCode.
|
|
|
|
/// # Example
|
|
|
|
/// ```
|
|
|
|
/// use klotski_ffi::AllCases;
|
|
|
|
///
|
|
|
|
/// let all_common_codes = AllCases::common_codes();
|
|
|
|
///
|
|
|
|
/// for common_code in &all_common_codes[..16] {
|
|
|
|
/// println!("{}", common_code);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
#[inline] |
|
|
|
pub fn common_codes() -> &'static Vec<CommonCode> { |
|
|
|
&(*ALL_COMMON_CODES) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn build_all_cases() -> Vec<u64> { |
|
|
|
unsafe { |
|
|
|
Core::all_cases_build(); |
|
|
|
let mut buffer: Vec<u64> = vec![0; Core::ALL_CASES_SIZE as usize]; |
|
|
|
Core::export_all_cases(&mut buffer[0]); |
|
|
|
Core::export_all_cases(buffer.as_mut_ptr()); |
|
|
|
buffer |
|
|
|
} |
|
|
|
} |
|
|
@ -29,49 +106,70 @@ fn build_basic_ranges() -> Vec<u32> { |
|
|
|
unsafe { |
|
|
|
Core::basic_ranges_build(); |
|
|
|
let mut buffer: Vec<u32> = vec![0; Core::BASIC_RANGES_SIZE as usize]; |
|
|
|
Core::export_basic_ranges(&mut buffer[0]); |
|
|
|
Core::export_basic_ranges(buffer.as_mut_ptr()); |
|
|
|
buffer |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#[cfg(test)] |
|
|
|
mod tests { |
|
|
|
use super::AllCases; |
|
|
|
use crypto::md5::Md5; |
|
|
|
use crypto::digest::Digest; |
|
|
|
use crate::all_cases::{ALL_CASES, all_cases_fetch, BASIC_RANGES, basic_ranges_fetch}; |
|
|
|
use super::{ALL_CASES, BASIC_RANGES}; |
|
|
|
use super::{ALL_RAW_CODES, ALL_SHORT_CODES, ALL_COMMON_CODES}; |
|
|
|
|
|
|
|
const ALL_CASES_MD5: &str = "3888e9fab8d3cbb50908b12b147cfb23"; |
|
|
|
const BASIC_RANGES_MD5: &str = "6f385dc171e201089ff96bb010b47212"; |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn all_cases() { |
|
|
|
assert_eq!(&(*ALL_CASES), all_cases_fetch()); |
|
|
|
fn raw_codes() { |
|
|
|
let tmp: Vec<u64> = ALL_RAW_CODES.iter() |
|
|
|
.map(|code| code.to_common_code().unwrap()) |
|
|
|
.collect(); |
|
|
|
assert_eq!(tmp, *ALL_CASES); |
|
|
|
assert_eq!(&*ALL_RAW_CODES, AllCases::raw_codes()); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn short_codes() { |
|
|
|
let tmp: Vec<u64> = ALL_SHORT_CODES.iter() |
|
|
|
.map(|code| code.to_common_code().unwrap()) |
|
|
|
.collect(); |
|
|
|
assert_eq!(tmp, *ALL_CASES); |
|
|
|
assert_eq!(&*ALL_SHORT_CODES, AllCases::short_codes()); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn basic_ranges() { |
|
|
|
assert_eq!(&(*BASIC_RANGES), basic_ranges_fetch()); |
|
|
|
fn common_codes() { |
|
|
|
let tmp: Vec<u64> = ALL_COMMON_CODES.iter() |
|
|
|
.map(|code| code.unwrap()) |
|
|
|
.collect(); |
|
|
|
assert_eq!(tmp, *ALL_CASES); |
|
|
|
assert_eq!(&*ALL_COMMON_CODES, AllCases::common_codes()); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn all_cases_data() { |
|
|
|
let mut md5 = Md5::new(); |
|
|
|
let mut tmp = String::new(); |
|
|
|
for &common_code in &(*ALL_CASES) { |
|
|
|
for &common_code in &*ALL_CASES { |
|
|
|
tmp.push_str(&format!("{:09X}\n", common_code)); |
|
|
|
} |
|
|
|
md5.input_str(&tmp); |
|
|
|
assert_eq!(md5.result_str(), ALL_CASES_MD5); |
|
|
|
assert_eq!(&*ALL_CASES, AllCases::all_cases()); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn basic_ranges_data() { |
|
|
|
let mut md5 = Md5::new(); |
|
|
|
let mut tmp = String::new(); |
|
|
|
for &range in &(*BASIC_RANGES) { |
|
|
|
for &range in &*BASIC_RANGES { |
|
|
|
tmp.push_str(&format!("{:08X}\n", range)); |
|
|
|
} |
|
|
|
md5.input_str(&tmp); |
|
|
|
assert_eq!(md5.result_str(), BASIC_RANGES_MD5); |
|
|
|
assert_eq!(&*BASIC_RANGES, AllCases::basic_ranges()); |
|
|
|
} |
|
|
|
} |
|
|
|