Browse Source

feat: more interfaces of `RsShortCode`

master
Dnomd343 1 month ago
parent
commit
e2acdf76af
  1. 3
      src/core_ffi/CMakeLists.txt
  2. 7
      src/core_ffi/rust_ffi/adapter/common_code.cc
  3. 32
      src/core_ffi/rust_ffi/adapter/short_code.cc
  4. 9
      src/core_ffi/rust_ffi/build.rs
  5. 10
      src/core_ffi/rust_ffi/include/common_code.h
  6. 17
      src/core_ffi/rust_ffi/include/interface.h
  7. 3
      src/core_ffi/rust_ffi/include/short_code.h
  8. 65
      src/core_ffi/rust_ffi/src/bridge.rs
  9. 30
      src/core_ffi/rust_ffi/src/main.rs

3
src/core_ffi/CMakeLists.txt

@ -20,8 +20,9 @@ if (KLSK_RUST_FFI)
else()
# just for IDE highlight
add_library(klotski_rust
rust_ffi/adapter/short_code.cc
rust_ffi/adapter/common_code.cc
rust_ffi/target/cxxbridge/rust_ffi/src/common_code.rs.cc
rust_ffi/target/cxxbridge/rust_ffi/src/bridge.rs.cc
)
target_include_directories(klotski_rust PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(klotski_rust PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/rust_ffi/target/cxxbridge)

7
src/core_ffi/rust_ffi/adapter/common_code.cc

@ -4,7 +4,6 @@
#include <common_code/common_code.h>
using klotski::codec::RawCode;
using klotski::codec::ShortCode;
using klotski::codec::CommonCode;
using klotski::mover::MaskMover;
@ -13,15 +12,15 @@ using klotski::ffi::RsShortCode;
using klotski::ffi::RsCommonCode;
// TODO: it seems that cxx.rs not support `std::optional`
uint64_t klotski::ffi::common_code_from_str(rust::Str s) {
std::string_view sv {s.data(), s.length()};
uint64_t klotski::ffi::common_code_from_str(const rust::Str s) {
const std::string_view sv {s.data(), s.length()};
if (const auto ret = CommonCode::from_string(sv); ret.has_value()) {
return ret.value().unwrap();
}
return 0x10FFFFFFFF; // return invalid value for now
}
bool klotski::ffi::common_code_check(uint64_t val) {
bool klotski::ffi::common_code_check(const uint64_t val) {
return CommonCode::check(val);
}

32
src/core_ffi/rust_ffi/adapter/short_code.cc

@ -0,0 +1,32 @@
#include "rust_ffi/include/short_code.h"
#include <short_code/short_code.h>
using klotski::codec::ShortCode;
using klotski::ffi::RsShortCode;
using klotski::ffi::RsCommonCode;
bool klotski::ffi::short_code_check(const uint32_t val) {
return ShortCode::check(val);
}
uint32_t klotski::ffi::short_code_from_str(const rust::Str s) {
const std::string_view sv {s.data(), s.length()};
if (const auto ret = ShortCode::from_string(sv); ret.has_value()) {
return ret.value().unwrap();
}
return 0xFFFFFFFF; // return invalid value for now
}
rust::String RsShortCode::to_string() const noexcept {
return ShortCode::unsafe_create(code).to_string();
}
RsCommonCode RsShortCode::to_common_code() const noexcept {
return {ShortCode::unsafe_create(code).to_common_code().unwrap()};
}
void klotski::ffi::short_code_speed_up(const bool fast_mode) {
ShortCode::speed_up(fast_mode);
}

9
src/core_ffi/rust_ffi/build.rs

@ -13,7 +13,6 @@ use cxx_build::CFG;
fn main() {
let dst = cmake::Config::new("klotski")
// .build_target("klotski_core")
.define("CARGO_BUILD:BOOL", "ON")
.define("KLSK_ENABLE_TESTING:BOOL", "OFF")
.define("KLSK_ENABLE_BENCHMARK:BOOL", "OFF")
@ -23,17 +22,19 @@ fn main() {
CFG.include_prefix = "rust_ffi";
cxx_build::bridge("src/common_code.rs")
cxx_build::bridge("src/bridge.rs")
.file("adapter/short_code.cc")
.file("adapter/common_code.cc")
.include("klotski/src/core")
.flag("-std=c++23")
.flag("-fno-rtti")
.flag("-fno-exceptions")
.include("klotski/src/core")
.compile("klotski");
println!("cargo:rustc-link-search=native={}", dst.display());
println!("cargo:rustc-link-lib=static=klotski_core");
println!("cargo:rerun-if-changed=src/bridge.rs");
println!("cargo:rerun-if-changed=adapter/short_code.cc");
println!("cargo:rerun-if-changed=adapter/common_code.cc");
println!("cargo:rerun-if-changed=src/common_code.rs");
}

10
src/core_ffi/rust_ffi/include/common_code.h

@ -1,11 +1,3 @@
#pragma once
#include "rust_ffi/src/common_code.rs.h"
namespace klotski::ffi {
bool common_code_check(uint64_t val);
uint64_t common_code_from_str(rust::Str s);
} // namespace klotski::ffi
#include "interface.h"

17
src/core_ffi/rust_ffi/include/interface.h

@ -0,0 +1,17 @@
#pragma once
#include "rust_ffi/src/bridge.rs.h"
namespace klotski::ffi {
bool short_code_check(uint32_t val);
bool common_code_check(uint64_t val);
uint32_t short_code_from_str(rust::Str s);
uint64_t common_code_from_str(rust::Str s);
void short_code_speed_up(bool fast_mode);
} // namespace klotski::ffi

3
src/core_ffi/rust_ffi/include/short_code.h

@ -0,0 +1,3 @@
#pragma once
#include "interface.h"

65
src/core_ffi/rust_ffi/src/common_code.rs → src/core_ffi/rust_ffi/src/bridge.rs

@ -45,11 +45,22 @@ mod ffi {
}
unsafe extern "C++" {
// include!("rust_ffi/include/short_code.h");
include!("rust_ffi/include/short_code.h");
// fn short_code_from_str(s: &str) -> RsShortCode;
/// only for internal use
fn short_code_check(val: u32) -> bool;
/// only for internal use
fn short_code_from_str(s: &str) -> u32;
/// Convert ShortCode to string form.
fn to_string(self: &RsShortCode) -> String;
// TODO: speed_up interface
/// Convert ShortCode to CommonCode.
fn to_common_code(self: &RsShortCode) -> RsCommonCode;
/// Build the conversion index for ShortCode.
fn short_code_speed_up(fast_mode: bool);
}
}
@ -63,12 +74,12 @@ impl CommonCode {
}
/// Create CommonCode without any check.
pub fn unsafe_create(code: u64) -> CommonCode {
CommonCode { code }
pub fn unsafe_create(code: u64) -> Self {
Self { code }
}
/// Create CommonCode with validity check.
pub fn create(code: u64) -> Option<CommonCode> {
pub fn create(code: u64) -> Option<Self> {
if Self::check(code) {
return Some(Self::unsafe_create(code));
}
@ -76,12 +87,12 @@ impl CommonCode {
}
/// Get the original u64 code.
pub fn unwrap(self: &CommonCode) -> u64 {
pub fn unwrap(self: &Self) -> u64 {
self.code
}
/// Create CommonCode from string form.
pub fn from_string(s: &str) -> Option<CommonCode> {
pub fn from_string(s: &str) -> Option<Self> {
let val = ffi::common_code_from_str(s);
if val < 0x10_FFFF_FFFF {
return Some(Self::unsafe_create(val));
@ -90,6 +101,44 @@ impl CommonCode {
}
}
impl ShortCode {
/// Check the validity of the original ShortCode.
pub fn check(code: u32) -> bool {
ffi::short_code_check(code)
}
/// Create ShortCode without any check.
pub fn unsafe_create(code: u32) -> Self {
Self { code }
}
/// Create ShortCode with validity check.
pub fn create(code: u32) -> Option<Self> {
if Self::check(code) {
return Some(Self::unsafe_create(code));
}
None
}
/// Get the original u32 code.
pub fn unwrap(self: &Self) -> u32 {
self.code
}
/// Create ShortCode from string form.
pub fn from_string(s: &str) -> Option<Self> {
let val = ffi::short_code_from_str(s);
if val != 0xFFFF_FFFF {
return Some(Self::unsafe_create(val));
}
None
}
pub fn speed_up(fast_mode: bool) {
ffi::short_code_speed_up(fast_mode)
}
}
impl PartialEq for CommonCode {
fn eq(&self, other: &Self) -> bool {
self.code == other.code

30
src/core_ffi/rust_ffi/src/main.rs

@ -1,8 +1,24 @@
mod common_code;
mod bridge;
use common_code::CommonCode;
use bridge::ShortCode;
use bridge::CommonCode;
fn main() {
fn short_code_demo() {
ShortCode::speed_up(false);
ShortCode::speed_up(true);
assert!(ShortCode::check(4091296));
let code = ShortCode::create(4091296).unwrap();
assert_eq!(code, ShortCode::from_string("4WVE1").unwrap());
assert_eq!(code, ShortCode::create(4091296).unwrap());
println!("code: {:?}", code.unwrap());
println!("string: {}", code.to_string());
println!("common_code: {:?}", code.to_common_code());
}
fn common_code_demo() {
assert!(CommonCode::check(0x1A9BF0C00));
let code = CommonCode::create(0x1A9BF0C00).unwrap();
assert_eq!(code, CommonCode::from_string("1A9BF0C").unwrap());
@ -23,3 +39,11 @@ fn main() {
println!("next_cases: {:?}", code.next_cases());
}
fn main() {
println!("----------------------------------------------------------------");
short_code_demo();
println!("----------------------------------------------------------------");
common_code_demo();
println!("----------------------------------------------------------------");
}

Loading…
Cancel
Save