Browse Source

WIP: basic API

develop
chodak166 4 months ago
parent
commit
846008de8e
  1. 1
      lib/src/common.rs
  2. 42
      lib/src/common/entities.rs
  3. 32
      lib/src/common/traits.rs
  4. 70
      lib/src/dictionary.rs
  5. 2
      lib/src/dictionary/dict_importer.rs
  6. 4
      lib/src/dictionary/infrastructure/json_file_dict_source.rs
  7. 3
      lib/src/dictionary/infrastructure/sqlite_dict_repository.rs
  8. 0
      lib/src/dictionary/service.rs
  9. 2
      lib/src/lib.rs

1
lib/src/common.rs

@ -2,6 +2,5 @@ pub mod entities;
pub mod errors; pub mod errors;
pub mod traits; pub mod traits;
pub use self::traits::DictRepository;
pub use self::traits::SystemDecoder; pub use self::traits::SystemDecoder;
pub use self::traits::SystemEncoder; pub use self::traits::SystemEncoder;

42
lib/src/common/entities.rs

@ -2,7 +2,7 @@ use super::errors::CodecError;
use serde::Serialize; use serde::Serialize;
use std::num::ParseIntError; use std::num::ParseIntError;
use std::ops::Deref; use std::ops::Deref;
use std::{collections::HashMap, u64}; use std::u64;
/// A number encoded as a sequence of words /// A number encoded as a sequence of words
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
@ -104,43 +104,3 @@ impl TryFrom<usize> for DecodedLength {
} }
} }
} }
// --- Dictionary ---
pub type DictEntryId = u64;
#[derive(Debug, Clone, PartialEq)]
pub struct DictEntry {
pub id: Option<DictEntryId>,
pub text: String,
pub metadata: HashMap<String, String>,
}
impl DictEntry {
pub fn new(id: Option<DictEntryId>, text: String) -> Self {
DictEntry {
id,
text,
metadata: HashMap::new(),
}
}
}
#[derive(Debug, Clone)]
pub struct Dict {
pub name: String,
pub entries: HashMap<DictEntryId, DictEntry>,
}
impl Dict {
pub fn new(name: String) -> Self {
Dict {
name,
entries: HashMap::new(),
}
}
pub fn add_entry(&mut self, entry: DictEntry) {
self.entries.insert(entry.id.unwrap(), entry);
}
}

32
lib/src/common/traits.rs

@ -1,8 +1,6 @@
use futures::stream::BoxStream;
use crate::common::{ use crate::common::{
entities::{DecodedValue, Dict, DictEntry, EncodedValue}, entities::{DecodedValue, EncodedValue},
errors::{CodecError, RepositoryError}, errors::CodecError,
}; };
pub trait SystemDecoder: Send + Sync { pub trait SystemDecoder: Send + Sync {
@ -13,29 +11,3 @@ pub trait SystemEncoder: Send + Sync {
fn initialize(&self) -> Result<(), CodecError>; fn initialize(&self) -> Result<(), CodecError>;
fn encode(&self, word: &str) -> Result<EncodedValue, CodecError>; fn encode(&self, word: &str) -> Result<EncodedValue, CodecError>;
} }
#[async_trait::async_trait]
pub trait DictRepository: Send + Sync {
fn use_dict(&mut self, name: &str);
async fn create_dict(&self) -> Result<(), RepositoryError>;
/// "Upsert" logic:
/// - If entry exists (by text), update metadata.
/// - If not, insert new.
/// - IDs are handled by the Database.
async fn save_entries(&self, entries: &[DictEntry]) -> Result<(), RepositoryError>;
/// Fetch a page of entries.
async fn fetch_many(&self, limit: usize, offset: usize) -> Result<Dict, RepositoryError>;
/// Returns a cold stream that fetches strings in chunks.
/// The stream yields `Result<Vec<String>, RepositoryError>`.
async fn stream_batches(
&self,
batch_size: usize,
) -> Result<BoxStream<'_, Result<Vec<String>, RepositoryError>>, RepositoryError>;
}
pub trait DictSource {
fn next_entry(&mut self) -> Option<Result<DictEntry, anyhow::Error>>;
}

70
lib/src/dictionary.rs

@ -1,6 +1,76 @@
mod dict_importer; mod dict_importer;
mod infrastructure; mod infrastructure;
use futures::stream::BoxStream;
use crate::common::errors::RepositoryError;
pub use self::dict_importer::DictImporter; pub use self::dict_importer::DictImporter;
pub use self::infrastructure::json_file_dict_source::JsonFileDictSource; pub use self::infrastructure::json_file_dict_source::JsonFileDictSource;
pub use self::infrastructure::sqlite_dict_repository::SqliteDictRepository; pub use self::infrastructure::sqlite_dict_repository::SqliteDictRepository;
use std::collections::HashMap;
pub type DictEntryId = u64;
#[derive(Debug, Clone, PartialEq)]
pub struct DictEntry {
pub id: Option<DictEntryId>,
pub text: String,
pub metadata: HashMap<String, String>,
}
impl DictEntry {
pub fn new(id: Option<DictEntryId>, text: String) -> Self {
DictEntry {
id,
text,
metadata: HashMap::new(),
}
}
}
#[derive(Debug, Clone)]
pub struct Dict {
pub name: String,
pub entries: HashMap<DictEntryId, DictEntry>,
}
impl Dict {
pub fn new(name: String) -> Self {
Dict {
name,
entries: HashMap::new(),
}
}
pub fn add_entry(&mut self, entry: DictEntry) {
self.entries.insert(entry.id.unwrap(), entry);
}
}
#[async_trait::async_trait]
pub trait DictRepository: Send + Sync {
fn use_dict(&mut self, name: &str);
async fn create_dict(&self) -> Result<(), RepositoryError>;
/// "Upsert" logic:
/// - If entry exists (by text), update metadata.
/// - If not, insert new.
/// - IDs are handled by the Database.
async fn save_entries(&self, entries: &[DictEntry]) -> Result<(), RepositoryError>;
/// Fetch a page of entries.
async fn fetch_many(&self, limit: usize, offset: usize) -> Result<Dict, RepositoryError>;
/// Returns a cold stream that fetches strings in chunks.
/// The stream yields `Result<Vec<String>, RepositoryError>`.
async fn stream_batches(
&self,
batch_size: usize,
) -> Result<BoxStream<'_, Result<Vec<String>, RepositoryError>>, RepositoryError>;
}
pub trait DictSource {
fn next_entry(&mut self) -> Option<Result<DictEntry, anyhow::Error>>;
}

2
lib/src/dictionary/dict_importer.rs

@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::common::traits::{DictRepository, DictSource}; use super::{DictRepository, DictSource};
pub struct DictImporter { pub struct DictImporter {
repo: Arc<dyn DictRepository>, repo: Arc<dyn DictRepository>,

4
lib/src/dictionary/infrastructure/json_file_dict_source.rs

@ -1,5 +1,5 @@
use crate::common::entities::DictEntry; use crate::dictionary::DictEntry;
use crate::common::traits::DictSource; use crate::dictionary::DictSource;
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;

3
lib/src/dictionary/infrastructure/sqlite_dict_repository.rs

@ -1,6 +1,5 @@
use crate::common::entities::{Dict, DictEntry};
use crate::common::errors::RepositoryError; use crate::common::errors::RepositoryError;
use crate::common::traits::DictRepository; use crate::dictionary::{Dict, DictEntry, DictRepository};
use futures::TryStreamExt; use futures::TryStreamExt;
use futures::stream::BoxStream; use futures::stream::BoxStream;

0
lib/src/dictionary/service.rs

2
lib/src/lib.rs

@ -12,9 +12,9 @@ mod common;
mod dictionary; mod dictionary;
pub mod sys_major; pub mod sys_major;
pub use self::common::DictRepository;
pub use self::common::SystemDecoder; pub use self::common::SystemDecoder;
pub use self::common::SystemEncoder; pub use self::common::SystemEncoder;
pub use self::dictionary::DictImporter; pub use self::dictionary::DictImporter;
pub use self::dictionary::DictRepository;
pub use self::dictionary::JsonFileDictSource; pub use self::dictionary::JsonFileDictSource;
pub use self::dictionary::SqliteDictRepository; pub use self::dictionary::SqliteDictRepository;

Loading…
Cancel
Save