Implement word search
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import 'package:jadb/models/jmdict/jmdict_kanji_info.dart';
|
||||
import 'package:jadb/models/jmdict/jmdict_reading_info.dart';
|
||||
import 'package:jadb/models/word_search/word_search_ruby.dart';
|
||||
import 'package:jadb/models/word_search/word_search_sense.dart';
|
||||
import 'package:jadb/models/word_search/word_search_sources.dart';
|
||||
|
||||
/// A class representing a single dictionary entry from a word search.
|
||||
class WordSearchResult {
|
||||
/// The ID of the entry in the database.
|
||||
final int entryId;
|
||||
|
||||
/// The variants of the word in Japanese.
|
||||
final List<WordSearchRuby> japanese;
|
||||
|
||||
/// Extra information about the kanji used in the word.
|
||||
final Map<String, JMdictKanjiInfo> kanjiInfo;
|
||||
|
||||
/// Extra information about the kana used in the word.
|
||||
final Map<String, JMdictReadingInfo> readingInfo;
|
||||
|
||||
/// The meanings of the word, including parts of speech and other information.
|
||||
final List<WordSearchSense> senses;
|
||||
|
||||
/// A class listing the sources used to make up the data for this word search result.
|
||||
final WordSearchSources sources;
|
||||
|
||||
const WordSearchResult({
|
||||
required this.entryId,
|
||||
required this.japanese,
|
||||
required this.kanjiInfo,
|
||||
required this.readingInfo,
|
||||
required this.senses,
|
||||
required this.sources,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'entryId': entryId,
|
||||
'japanese': japanese.map((e) => e.toJson()).toList(),
|
||||
'kanjiInfo':
|
||||
kanjiInfo.map((key, value) => MapEntry(key, value.toJson())),
|
||||
'readingInfo':
|
||||
readingInfo.map((key, value) => MapEntry(key, value.toJson())),
|
||||
'senses': senses.map((e) => e.toJson()).toList(),
|
||||
'sources': sources.toJson(),
|
||||
};
|
||||
|
||||
factory WordSearchResult.fromJson(Map<String, dynamic> json) =>
|
||||
WordSearchResult(
|
||||
entryId: json['entryId'] as int,
|
||||
japanese: (json['japanese'] as List<dynamic>)
|
||||
.map((e) => WordSearchRuby.fromJson(e))
|
||||
.toList(),
|
||||
kanjiInfo: (json['kanjiInfo'] as Map<String, dynamic>).map(
|
||||
(key, value) => MapEntry(key, JMdictKanjiInfo.fromJson(value)),
|
||||
),
|
||||
readingInfo: (json['readingInfo'] as Map<String, dynamic>).map(
|
||||
(key, value) => MapEntry(key, JMdictReadingInfo.fromJson(value)),
|
||||
),
|
||||
senses: (json['senses'] as List<dynamic>)
|
||||
.map((e) => WordSearchSense.fromJson(e))
|
||||
.toList(),
|
||||
sources: WordSearchSources.fromJson(json['sources']),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/// A pair of base and optional furigana.
|
||||
class WordSearchRuby {
|
||||
/// Base part. Could be a kanji or a reading.
|
||||
String base;
|
||||
|
||||
/// Furigana, if applicable.
|
||||
String? furigana;
|
||||
|
||||
WordSearchRuby({
|
||||
required this.base,
|
||||
this.furigana,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'base': base,
|
||||
'furigana': furigana,
|
||||
};
|
||||
|
||||
factory WordSearchRuby.fromJson(Map<String, dynamic> json) => WordSearchRuby(
|
||||
base: json['base'] as String,
|
||||
furigana: json['furigana'] as String?,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import 'package:jadb/models/jmdict/jmdict_dialect.dart';
|
||||
import 'package:jadb/models/jmdict/jmdict_field.dart';
|
||||
import 'package:jadb/models/jmdict/jmdict_misc.dart';
|
||||
import 'package:jadb/models/jmdict/jmdict_pos.dart';
|
||||
import 'package:jadb/models/word_search/word_search_xref_entry.dart';
|
||||
|
||||
class WordSearchSense {
|
||||
/// The meaning(s) of the word.
|
||||
final List<String> englishDefinitions;
|
||||
|
||||
/// Type of word (Noun, Verb, etc.).
|
||||
final List<JMdictPOS> partsOfSpeech;
|
||||
|
||||
/// Relevant words (might include synonyms).
|
||||
final List<WordSearchXrefEntry> seeAlso;
|
||||
|
||||
/// Words with opposite meaning.
|
||||
final List<WordSearchXrefEntry> antonyms;
|
||||
|
||||
/// Restrictions on which of the readings of the parent entry this sense applies to.
|
||||
final List<String> restrictedToReading;
|
||||
|
||||
/// Restrictions on which of the kanji of the parent entry this sense applies to.
|
||||
final List<String> restrictedToKanji;
|
||||
|
||||
/// Tags for which domains or fields of expertise that this sense is relevant to.
|
||||
final List<JMdictField> fields;
|
||||
|
||||
/// Tags for which dialects this sense is used in.
|
||||
final List<JMdictDialect> dialects;
|
||||
|
||||
/// Tags for miscellaneous information.
|
||||
final List<JMdictMisc> misc;
|
||||
|
||||
/// Extra information about the sense.
|
||||
final List<String> info;
|
||||
|
||||
// TODO: there is a lot more info to collect in the languageSource data
|
||||
|
||||
/// Information about the the origin of the word, if loaned from another language.
|
||||
final List<String> languageSource;
|
||||
|
||||
// TODO: add example sentences
|
||||
|
||||
const WordSearchSense({
|
||||
required this.englishDefinitions,
|
||||
required this.partsOfSpeech,
|
||||
required this.seeAlso,
|
||||
required this.antonyms,
|
||||
required this.restrictedToReading,
|
||||
required this.restrictedToKanji,
|
||||
required this.fields,
|
||||
required this.dialects,
|
||||
required this.misc,
|
||||
required this.info,
|
||||
required this.languageSource,
|
||||
});
|
||||
|
||||
bool get isEmpty =>
|
||||
englishDefinitions.isEmpty &&
|
||||
partsOfSpeech.isEmpty &&
|
||||
seeAlso.isEmpty &&
|
||||
antonyms.isEmpty &&
|
||||
restrictedToReading.isEmpty &&
|
||||
restrictedToKanji.isEmpty &&
|
||||
fields.isEmpty &&
|
||||
dialects.isEmpty &&
|
||||
misc.isEmpty &&
|
||||
info.isEmpty &&
|
||||
languageSource.isEmpty;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'englishDefinitions': englishDefinitions,
|
||||
'partsOfSpeech': partsOfSpeech.map((e) => e.toJson()).toList(),
|
||||
'seeAlso': seeAlso.map((e) => e.toJson()).toList(),
|
||||
'antonyms': antonyms.map((e) => e.toJson()).toList(),
|
||||
'restrictedToReading': restrictedToReading,
|
||||
'restrictedToKanji': restrictedToKanji,
|
||||
'fields': fields.map((e) => e.toJson()).toList(),
|
||||
'dialects': dialects.map((e) => e.toJson()).toList(),
|
||||
'misc': misc.map((e) => e.toJson()).toList(),
|
||||
'info': info,
|
||||
'languageSource': languageSource,
|
||||
};
|
||||
|
||||
factory WordSearchSense.fromJson(Map<String, dynamic> json) =>
|
||||
WordSearchSense(
|
||||
englishDefinitions: List<String>.from(json['englishDefinitions']),
|
||||
partsOfSpeech: (json['partsOfSpeech'] as List)
|
||||
.map((e) => JMdictPOS.fromJson(e))
|
||||
.toList(),
|
||||
seeAlso: (json['seeAlso'] as List)
|
||||
.map((e) => WordSearchXrefEntry.fromJson(e))
|
||||
.toList(),
|
||||
antonyms: (json['antonyms'] as List)
|
||||
.map((e) => WordSearchXrefEntry.fromJson(e))
|
||||
.toList(),
|
||||
restrictedToReading: List<String>.from(json['restrictedToReading']),
|
||||
restrictedToKanji: List<String>.from(json['restrictedToKanji']),
|
||||
fields: (json['fields'] as List)
|
||||
.map((e) => JMdictField.fromJson(e))
|
||||
.toList(),
|
||||
dialects: (json['dialects'] as List)
|
||||
.map((e) => JMdictDialect.fromJson(e))
|
||||
.toList(),
|
||||
misc:
|
||||
(json['misc'] as List).map((e) => JMdictMisc.fromJson(e)).toList(),
|
||||
info: List<String>.from(json['info']),
|
||||
languageSource: List<String>.from(json['languageSource']),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/// A class representing which sources were used to make up the data for
|
||||
/// a word search result.
|
||||
class WordSearchSources {
|
||||
/// Whether JMdict was used.
|
||||
final bool jmdict;
|
||||
|
||||
/// Whether JMnedict was used.
|
||||
final bool jmnedict;
|
||||
|
||||
const WordSearchSources({
|
||||
this.jmdict = true,
|
||||
this.jmnedict = false,
|
||||
});
|
||||
|
||||
Map<String, Object?> get sqlValue => {
|
||||
'jmdict': jmdict,
|
||||
'jmnedict': jmnedict,
|
||||
};
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'jmdict': jmdict,
|
||||
'jmnedict': jmnedict,
|
||||
};
|
||||
|
||||
factory WordSearchSources.fromJson(Map<String, dynamic> json) =>
|
||||
WordSearchSources(
|
||||
jmdict: json['jmdict'] as bool? ?? true,
|
||||
jmnedict: json['jmnedict'] as bool? ?? false,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/// A cross-reference entry from one word-result to another entry.
|
||||
class WordSearchXrefEntry {
|
||||
/// The ID of the entry that this entry cross-references to.
|
||||
final int entryId;
|
||||
|
||||
/// Whether the entryId was ambiguous during the creation of the
|
||||
/// database (and hence might be incorrect).
|
||||
final bool ambiguous;
|
||||
|
||||
const WordSearchXrefEntry({
|
||||
required this.entryId,
|
||||
required this.ambiguous,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'entryId': entryId,
|
||||
'ambiguous': ambiguous,
|
||||
};
|
||||
|
||||
factory WordSearchXrefEntry.fromJson(Map<String, dynamic> json) =>
|
||||
WordSearchXrefEntry(
|
||||
entryId: json['entryId'] as int,
|
||||
ambiguous: json['ambiguous'] as bool,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user