@ -2,9 +2,8 @@ use std::collections::BinaryHeap;
use std ::collections ::HashMap ;
use std ::ops ::Deref ;
use fuzzy_matcher ::FuzzyMatcher ;
use fuzzy_matcher ::skim ::SkimMatcherV2 ;
use multi_map::MultiMap ;
use fuzzy_matcher::FuzzyMatcher ;
use serde_derive ::Deserialize ;
use serde_derive ::Serialize ;
@ -16,9 +15,9 @@ type UnprocessedAreas = Vec<UnprocessedArea>;
struct UnprocessedArea {
#[ serde(rename = " Id " ) ]
pub named_id : String ,
#[ serde(rename = " _rid " ) ]
pub key_id : usize ,
pub key_id : usize ,
#[ serde(rename = " Name " ) ]
pub name : String ,
@ -39,10 +38,10 @@ struct UnprocessedArea {
pub is_vaal_area : bool ,
#[ serde(rename = " Unknown64 " ) ]
pub unknown64 : bool ,
pub unknown64 : bool ,
#[ serde(rename = " Unknown9 " ) ]
pub unknown9 : i64 ,
pub unknown9 : i64 ,
}
pub type AreaName = String ;
@ -52,11 +51,14 @@ pub struct WorldArea {
#[ serde(rename = " Name " ) ]
pub name : String ,
#[ serde(rename = " NamedId " ) ]
pub named_id : String ,
#[ serde(rename = " Act " ) ]
pub act : i64 ,
#[ serde(rename = " _rid " ) ]
pub key_id : usize ,
pub key_id : usize ,
#[ serde(rename = " IsTown " ) ]
pub is_town : bool ,
@ -69,94 +71,79 @@ pub struct WorldArea {
}
pub type AreaId = usize ;
pub type WorldAreasMap = MultiMap< AreaName , AreaId , WorldArea > ;
pub type WorldAreasMap = HashMap< String , WorldArea > ;
#[ allow(dead_code) ]
pub fn load_world_areas_map ( content : & ' static str ) -> WorldAreasMap {
let mut world_area_map = WorldAreasMap ::new ( ) ;
serde_json ::from_str ::< HashMap < AreaName , WorldArea > > ( content )
. expect ( "Could not load world areas json" )
. into_iter ( )
. for_each ( | ( area_name , world_area ) |
{
world_area_map . insert ( area_name , world_area . key_id , world_area ) ;
} ) ;
world_area_map
serde_json ::from_str ::< WorldAreasMap > ( content )
. expect ( "Could not load world areas json" )
}
#[ macro_export ]
macro_rules! load_world_areas {
( $e :expr ) = > {
crate ::world_area ::load_world_areas_map ( & include_str! ( $e ) )
} ;
( $e :expr ) = > {
crate ::world_area ::load_world_areas_map ( & include_str! ( $e ) )
} ;
}
#[ allow(dead_code) ]
pub struct WorldAreas {
pub areas_map : WorldAreasMap ,
matcher : Matcher ,
pub areas_map : WorldAreasMap ,
matcher : Matcher ,
}
impl WorldAreas {
#[ allow(dead_code) ]
pub fn new ( areas : WorldAreasMap , matcher : Matcher ) -> Self {
Self {
areas_map : areas ,
matcher ,
}
}
#[ allow(dead_code) ]
pub fn fuzzy_area ( & self , count : usize , area : & str ) -> Vec < WorldArea > {
let mut matches = Vec ::new ( ) ;
for ( _k , ( _key_id , v ) ) in & self . areas_map {
if let Some ( mut score ) = self . matcher . fuzzy_match ( & v . name , area ) {
if v . name . contains ( area ) {
score = i64 ::MAX ;
}
let f_entry = FEntry { area : v . clone ( ) , score } ;
matches . push ( f_entry ) ;
}
}
matches . sort_by ( | entry1 , entry2 | {
entry1 . score . cmp ( & entry2 . score ) . reverse ( )
. then ( entry1 . area . key_id . cmp ( & entry2 . area . key_id ) )
} ) ;
let matches_areas = matches
. into_iter ( )
. map ( | entry | entry . area )
. take ( count )
. collect ::< Vec < WorldArea > > ( ) ;
matches_areas
}
#[ allow(dead_code) ]
pub fn by_area_id ( & self , key : AreaId ) -> Option < & WorldArea > {
self . areas_map . get_alt ( & key )
}
#[ allow(dead_code) ]
pub fn by_area_name ( & self , key : AreaName ) -> Option < & WorldArea > {
self . areas_map . get ( & key )
}
}
#[ allow(dead_code) ]
pub fn new ( areas : WorldAreasMap , matcher : Matcher ) -> Self {
Self {
areas_map : areas ,
matcher ,
}
}
#[ allow(dead_code) ]
pub fn fuzzy_area ( & self , count : usize , area : & str ) -> Vec < WorldArea > {
let mut matches = Vec ::new ( ) ;
for ( _key_id , v ) in & self . areas_map {
if let Some ( mut score ) = self . matcher . fuzzy_match ( & v . name , area ) {
if v . name . contains ( area ) {
score = i64 ::MAX ;
}
let f_entry = FEntry {
area : v . clone ( ) ,
score ,
} ;
matches . push ( f_entry ) ;
}
}
matches . sort_by ( | entry1 , entry2 | {
entry1
. score
. cmp ( & entry2 . score )
. reverse ( )
. then ( entry1 . area . key_id . cmp ( & entry2 . area . key_id ) )
} ) ;
let matches_areas = matches
. into_iter ( )
. map ( | entry | entry . area )
. take ( count )
. collect ::< Vec < WorldArea > > ( ) ;
matches_areas
}
#[ allow(dead_code) ]
pub fn by_area_id ( & self , key : String ) -> Option < & WorldArea > {
self . areas_map . get ( & key )
}
}
#[ derive(PartialEq, Eq, Clone, Debug) ]
struct FEntry {
area : WorldArea ,
score : i64 ,
area : WorldArea ,
score : i64 ,
}
impl Ord for FEntry {
@ -167,25 +154,23 @@ impl Ord for FEntry {
impl PartialOrd for FEntry {
fn partial_cmp ( & self , other : & Self ) -> Option < std ::cmp ::Ordering > {
Some ( self . score . cmp ( & other . score ) )
Some ( self . score . cmp ( & other . score ) )
}
}
pub struct Matcher ( SkimMatcherV2 ) ;
impl Matcher {
#[ allow(dead_code) ]
pub fn new ( ) -> Self {
let matcher = SkimMatcherV2 ::default ( )
. ignore_case ( )
. use_cache ( true ) ;
Matcher ( matcher )
}
#[ allow(dead_code) ]
pub fn new ( ) -> Self {
let matcher = SkimMatcherV2 ::default ( ) . ignore_case ( ) . use_cache ( true ) ;
Matcher ( matcher )
}
}
impl Deref for Matcher {
type Target = SkimMatcherV2 ;
type Target = SkimMatcherV2 ;
fn deref ( & self ) -> & Self ::Target {
& self . 0
@ -193,69 +178,73 @@ impl Deref for Matcher {
}
impl Matcher {
#[ allow(dead_code) ]
pub fn fuzzy_area ( & self , areas : & WorldAreasMap , area : & str ) -> Vec < WorldArea > {
let mut matches : BinaryHeap < FEntry > = BinaryHeap ::new ( ) ;
for ( _k , ( _key_id , v ) ) in areas {
//println!("k: {:?}\nv: {:?}\n\n", k, v);
if let Some ( score ) = self . fuzzy_match ( & v . name , area ) {
let f_entry = FEntry { area : v . clone ( ) , score } ;
matches . push ( f_entry ) ;
}
}
let mut values = matches . into_iter ( ) ;
let mut return_vec = Vec ::new ( ) ;
for _i in 0 .. 30 {
if let Some ( value ) = values . next ( ) {
return_vec . push ( value . area . clone ( ) ) ;
} else {
break ;
}
}
return_vec
}
#[ allow(dead_code) ]
pub fn fuzzy_area ( & self , areas : & WorldAreasMap , area : & str ) -> Vec < WorldArea > {
let mut matches : BinaryHeap < FEntry > = BinaryHeap ::new ( ) ;
for ( _key_id , v ) in areas {
if let Some ( score ) = self . fuzzy_match ( & v . name , area ) {
let f_entry = FEntry {
area : v . clone ( ) ,
score ,
} ;
matches . push ( f_entry ) ;
}
}
let mut values = matches . into_iter ( ) ;
let mut return_vec = Vec ::new ( ) ;
for _i in 0 .. 30 {
if let Some ( value ) = values . next ( ) {
return_vec . push ( value . area . clone ( ) ) ;
} else {
break ;
}
}
return_vec
}
}
//TODO: Multimap
#[ allow(dead_code) ]
pub fn repack ( content : & str , out_path : & str ) {
let areas_json = serde_json ::from_str ::< UnprocessedAreas > ( content ) ;
let area_map = areas_json . expect ( "Could not read world areas" ) . into_iter ( ) . filter_map ( | w_a | {
if
w_a . act < 11 & &
! w_a . is_vaal_area & &
! w_a . connections_world_areas_keys . is_empty ( ) & &
! w_a . unknown64 & &
! w_a . named_id . starts_with ( "Map" ) & &
! w_a . named_id . starts_with ( "Descent" ) & &
! w_a . named_id . starts_with ( "EndlessLedge" ) & &
w_a . unknown9 ! = 20
{
Some ( (
w_a . named_id ,
WorldArea {
name : w_a . name ,
act : w_a . act ,
is_town : w_a . is_town ,
has_waypoint : w_a . has_waypoint ,
connections_world_areas_keys : w_a . connections_world_areas_keys ,
key_id : w_a . key_id ,
}
) )
} else {
None
}
} ) . collect ::< HashMap < AreaName , WorldArea > > ( ) ;
let new_json = serde_json ::to_string ( & area_map ) . unwrap ( ) ;
std ::fs ::write ( out_path , & new_json ) . expect ( "Could not write to file" ) ;
}
let areas_json = serde_json ::from_str ::< UnprocessedAreas > ( content ) ;
let area_map = areas_json
. expect ( "Could not read world areas" )
. into_iter ( )
. filter_map ( | w_a | {
if w_a . act < 11
& & ! w_a . is_vaal_area
& & ! w_a . connections_world_areas_keys . is_empty ( )
& & ! w_a . unknown64
& & ! w_a . named_id . starts_with ( "Map" )
& & ! w_a . named_id . starts_with ( "Descent" )
& & ! w_a . named_id . starts_with ( "EndlessLedge" )
& & w_a . unknown9 ! = 20
{
Some ( (
w_a . named_id . clone ( ) ,
WorldArea {
name : w_a . name ,
named_id : w_a . named_id ,
act : w_a . act ,
is_town : w_a . is_town ,
has_waypoint : w_a . has_waypoint ,
connections_world_areas_keys : w_a . connections_world_areas_keys ,
key_id : w_a . key_id ,
} ,
) )
} else {
None
}
} )
. collect ::< WorldAreasMap > ( ) ;
let new_json = serde_json ::to_string ( & area_map ) . unwrap ( ) ;
std ::fs ::write ( out_path , & new_json ) . expect ( "Could not write to file" ) ;
}