83 lines
3 KiB
Rust
83 lines
3 KiB
Rust
mod actual_listings;
|
||
pub mod area_crime_averages;
|
||
pub mod crime_by_year;
|
||
pub mod crime_records;
|
||
mod developments;
|
||
mod places;
|
||
mod poi;
|
||
pub mod postcode_population;
|
||
mod postcodes;
|
||
mod property;
|
||
pub mod spill;
|
||
pub mod travel_time;
|
||
|
||
/// Apostrophe-like code points that should be elided (not treated as word breaks) when
|
||
/// normalizing search text. Keyboards, autocorrect and copy-paste all produce different glyphs
|
||
/// for what users mean as an apostrophe; treating any of them as a separator turns "King's Cross"
|
||
/// into the tokens `king s cross` and breaks matching. Covers the straight ASCII apostrophe, the
|
||
/// typographic left/right single quotes, grave/acute accents, the modifier-letter apostrophes,
|
||
/// prime, and the fullwidth apostrophe.
|
||
pub(crate) fn is_apostrophe(ch: char) -> bool {
|
||
matches!(
|
||
ch,
|
||
'\u{0027}' // ' APOSTROPHE
|
||
| '\u{0060}' // ` GRAVE ACCENT
|
||
| '\u{00B4}' // ´ ACUTE ACCENT
|
||
| '\u{02B9}' // ʹ MODIFIER LETTER PRIME
|
||
| '\u{02BB}' // ʻ MODIFIER LETTER TURNED COMMA (ʻokina)
|
||
| '\u{02BC}' // ʼ MODIFIER LETTER APOSTROPHE
|
||
| '\u{2018}' // ' LEFT SINGLE QUOTATION MARK
|
||
| '\u{2019}' // ' RIGHT SINGLE QUOTATION MARK
|
||
| '\u{201B}' // ‛ SINGLE HIGH-REVERSED-9 QUOTATION MARK
|
||
| '\u{2032}' // ′ PRIME
|
||
| '\u{FF07}' // ' FULLWIDTH APOSTROPHE
|
||
)
|
||
}
|
||
|
||
fn panic_payload_message(payload: &(dyn std::any::Any + Send)) -> String {
|
||
if let Some(message) = payload.downcast_ref::<&'static str>() {
|
||
(*message).to_string()
|
||
} else if let Some(message) = payload.downcast_ref::<String>() {
|
||
message.clone()
|
||
} else {
|
||
"unknown panic payload".to_string()
|
||
}
|
||
}
|
||
|
||
pub(super) fn run_polars_io<T, F>(work: F) -> anyhow::Result<T>
|
||
where
|
||
T: Send,
|
||
F: FnOnce() -> anyhow::Result<T> + Send,
|
||
{
|
||
if tokio::runtime::Handle::try_current().is_err() {
|
||
return work();
|
||
}
|
||
|
||
std::thread::scope(|scope| {
|
||
scope.spawn(work).join().map_err(|payload| {
|
||
anyhow::anyhow!(
|
||
"Polars worker thread panicked: {}",
|
||
panic_payload_message(payload.as_ref())
|
||
)
|
||
})?
|
||
})
|
||
}
|
||
|
||
pub use actual_listings::{ActualListing, ActualListingData};
|
||
pub use area_crime_averages::AreaCrimeAverages;
|
||
pub use crime_by_year::CrimeByYearData;
|
||
pub use crime_records::CrimeRecords;
|
||
pub use developments::{DevelopmentData, DevelopmentSite};
|
||
pub use places::{
|
||
compute_trigrams, normalize_search_text, place_alias_tokens, trigram_similarity, PlaceData,
|
||
};
|
||
pub use poi::{resolve_poi_category_filter, POICategoryGroup, POIData, SchoolMetadata};
|
||
pub use postcode_population::PostcodePopulation;
|
||
pub use postcodes::{OutcodeData, PostcodeData};
|
||
pub use property::{
|
||
combine_nearest_distances, combined_station_feature_name,
|
||
combined_station_source_feature_names, precompute_h3, FeatureStats, Histogram, HistoricalPrice,
|
||
PostcodePoiMetrics, PropertyData, QuantRef, RenovationEvent, TenureEvent,
|
||
COMBINED_STATION_CATEGORY,
|
||
};
|
||
pub use travel_time::{slugify, TravelTimeStore};
|