mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Use a separate service definition for backend-only services
Realised this is clearer than tagging each method individually. The enum has been retained for the case where we want to implement the backend method separately from the collection one.
This commit is contained in:
parent
6f9b152028
commit
46722d792d
8 changed files with 51 additions and 79 deletions
|
@ -4,18 +4,10 @@ option java_multiple_files = true;
|
|||
|
||||
import "anki/generic.proto";
|
||||
import "anki/scheduler.proto";
|
||||
import "anki/codegen.proto";
|
||||
|
||||
package anki.ankidroid;
|
||||
|
||||
service AnkidroidService {
|
||||
rpc SchedTimingTodayLegacy(SchedTimingTodayLegacyRequest)
|
||||
returns (scheduler.SchedTimingTodayResponse) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc LocalMinutesWestLegacy(generic.Int64) returns (generic.Int32) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc RunDbCommand(generic.Json) returns (generic.Json);
|
||||
rpc RunDbCommandProto(generic.Json) returns (DbResponse);
|
||||
rpc InsertForId(generic.Json) returns (generic.Int64);
|
||||
|
@ -23,15 +15,17 @@ service AnkidroidService {
|
|||
rpc FlushAllQueries(generic.Empty) returns (generic.Empty);
|
||||
rpc FlushQuery(generic.Int32) returns (generic.Empty);
|
||||
rpc GetNextResultPage(GetNextResultPageRequest) returns (DbResponse);
|
||||
rpc SetPageSize(generic.Int64) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc GetColumnNamesFromQuery(generic.String) returns (generic.StringList);
|
||||
rpc GetActiveSequenceNumbers(generic.Empty)
|
||||
returns (GetActiveSequenceNumbersResponse);
|
||||
rpc DebugProduceError(generic.String) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
}
|
||||
|
||||
service BackendAnkidroidService {
|
||||
rpc SchedTimingTodayLegacy(SchedTimingTodayLegacyRequest)
|
||||
returns (scheduler.SchedTimingTodayResponse);
|
||||
rpc LocalMinutesWestLegacy(generic.Int64) returns (generic.Int32);
|
||||
rpc SetPageSize(generic.Int64) returns (generic.Empty);
|
||||
rpc DebugProduceError(generic.String) returns (generic.Empty);
|
||||
}
|
||||
|
||||
message DebugActiveDatabaseSequenceNumbersResponse {
|
||||
|
|
|
@ -28,7 +28,7 @@ service CardRenderingService {
|
|||
rpc DecodeIriPaths(generic.String) returns (generic.String);
|
||||
rpc StripHtml(StripHtmlRequest) returns (generic.String) {
|
||||
// a bunch of our unit tests access this without a collection
|
||||
option (codegen.rust_methods) = RUST_METHODS_COLLECTION_AND_MANUAL_BACKEND;
|
||||
option (codegen.backend_method) = BACKEND_METHOD_IMPLEMENT;
|
||||
}
|
||||
rpc CompareAnswer(CompareAnswerRequest) returns (generic.String);
|
||||
rpc ExtractClozeForTyping(ExtractClozeForTypingRequest)
|
||||
|
|
|
@ -8,21 +8,18 @@ package anki.codegen;
|
|||
import "google/protobuf/descriptor.proto";
|
||||
|
||||
extend google.protobuf.MethodOptions {
|
||||
RustMethods rust_methods = 50000;
|
||||
BackendMethod backend_method = 50000;
|
||||
}
|
||||
|
||||
message MethodOptions {
|
||||
RustMethods rust_methods = 50000;
|
||||
BackendMethod backend_method = 50000;
|
||||
}
|
||||
|
||||
enum RustMethods {
|
||||
enum BackendMethod {
|
||||
/// Used for typical collection-based operations. We must implement the
|
||||
// method on Collection. The same method is automatically implemented on
|
||||
// Backend, which forwards to Collection.
|
||||
RUST_METHODS_COLLECTION_AND_AUTO_BACKEND = 0;
|
||||
/// Method only makes sense on the backend (eg one that closes and reopens
|
||||
/// the collection). Backend method needs to be implemented.
|
||||
RUST_METHODS_BACKEND_ONLY = 1;
|
||||
BACKEND_METHOD_DELEGATE = 0;
|
||||
/// Both the backend and collection need to implement the method; there
|
||||
/// is no auto-delegation. Can be used to provide a method on both, but
|
||||
/// skip the Collection mutex lock when a backend handle is available.
|
||||
|
@ -30,5 +27,5 @@ enum RustMethods {
|
|||
/// method in other services that doesn't happen to need the collection,
|
||||
/// we just delegate to the collection method for convenience, and to make
|
||||
/// sure it's available even if the consumer is not using Backend.
|
||||
RUST_METHODS_COLLECTION_AND_MANUAL_BACKEND = 2;
|
||||
BACKEND_METHOD_IMPLEMENT = 1;
|
||||
}
|
||||
|
|
|
@ -8,15 +8,8 @@ option java_multiple_files = true;
|
|||
package anki.collection;
|
||||
|
||||
import "anki/generic.proto";
|
||||
import "anki/codegen.proto";
|
||||
|
||||
service CollectionService {
|
||||
rpc OpenCollection(OpenCollectionRequest) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc CloseCollection(CloseCollectionRequest) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc CheckDatabase(generic.Empty) returns (CheckDatabaseResponse);
|
||||
rpc GetUndoStatus(generic.Empty) returns (UndoStatus);
|
||||
rpc Undo(generic.Empty) returns (OpChangesAfterUndo);
|
||||
|
@ -25,18 +18,19 @@ service CollectionService {
|
|||
rpc MergeUndoEntries(generic.UInt32) returns (OpChanges);
|
||||
rpc LatestProgress(generic.Empty) returns (Progress);
|
||||
rpc SetWantsAbort(generic.Empty) returns (generic.Empty);
|
||||
}
|
||||
|
||||
service BackendCollectionService {
|
||||
rpc OpenCollection(OpenCollectionRequest) returns (generic.Empty);
|
||||
rpc CloseCollection(CloseCollectionRequest) returns (generic.Empty);
|
||||
// Create a no-media backup. Caller must ensure there is no active
|
||||
// transaction. Unlike a collection export, does not require reopening the DB,
|
||||
// as there is no downgrade step.
|
||||
// Returns false if it's not time to make a backup yet.
|
||||
rpc CreateBackup(CreateBackupRequest) returns (generic.Bool) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc CreateBackup(CreateBackupRequest) returns (generic.Bool);
|
||||
// If a backup is running, wait for it to complete. Will return an error
|
||||
// if the backup encountered an error.
|
||||
rpc AwaitBackupCompletion(generic.Empty) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc AwaitBackupCompletion(generic.Empty) returns (generic.Empty);
|
||||
}
|
||||
|
||||
message OpenCollectionRequest {
|
||||
|
|
|
@ -12,13 +12,13 @@ import "anki/codegen.proto";
|
|||
|
||||
service I18nService {
|
||||
rpc TranslateString(TranslateStringRequest) returns (generic.String) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_COLLECTION_AND_MANUAL_BACKEND;
|
||||
option (codegen.backend_method) = BACKEND_METHOD_IMPLEMENT;
|
||||
}
|
||||
rpc FormatTimespan(FormatTimespanRequest) returns (generic.String) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_COLLECTION_AND_MANUAL_BACKEND;
|
||||
option (codegen.backend_method) = BACKEND_METHOD_IMPLEMENT;
|
||||
}
|
||||
rpc I18nResources(I18nResourcesRequest) returns (generic.Json) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_COLLECTION_AND_MANUAL_BACKEND;
|
||||
option (codegen.backend_method) = BACKEND_METHOD_IMPLEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,6 @@ import "anki/generic.proto";
|
|||
import "anki/codegen.proto";
|
||||
|
||||
service ImportExportService {
|
||||
rpc ImportCollectionPackage(ImportCollectionPackageRequest)
|
||||
returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc ExportCollectionPackage(ExportCollectionPackageRequest)
|
||||
returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc ImportAnkiPackage(ImportAnkiPackageRequest) returns (ImportResponse);
|
||||
rpc ExportAnkiPackage(ExportAnkiPackageRequest) returns (generic.UInt32);
|
||||
rpc GetCsvMetadata(CsvMetadataRequest) returns (CsvMetadata);
|
||||
|
@ -32,6 +24,13 @@ service ImportExportService {
|
|||
rpc ImportJsonString(generic.String) returns (ImportResponse);
|
||||
}
|
||||
|
||||
service BackendImportExportService {
|
||||
rpc ImportCollectionPackage(ImportCollectionPackageRequest)
|
||||
returns (generic.Empty);
|
||||
rpc ExportCollectionPackage(ExportCollectionPackageRequest)
|
||||
returns (generic.Empty);
|
||||
}
|
||||
|
||||
message ImportCollectionPackageRequest {
|
||||
string col_path = 1;
|
||||
string backup_path = 2;
|
||||
|
|
|
@ -8,33 +8,16 @@ option java_multiple_files = true;
|
|||
package anki.sync;
|
||||
|
||||
import "anki/generic.proto";
|
||||
import "anki/codegen.proto";
|
||||
|
||||
service SyncService {
|
||||
rpc SyncMedia(SyncAuth) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc AbortMediaSync(generic.Empty) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc SyncLogin(SyncLoginRequest) returns (SyncAuth) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc SyncStatus(SyncAuth) returns (SyncStatusResponse) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc SyncCollection(SyncAuth) returns (SyncCollectionResponse) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc FullUpload(SyncAuth) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc FullDownload(SyncAuth) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
rpc AbortSync(generic.Empty) returns (generic.Empty) {
|
||||
option (codegen.rust_methods) = RUST_METHODS_BACKEND_ONLY;
|
||||
}
|
||||
service BackendSyncService {
|
||||
rpc SyncMedia(SyncAuth) returns (generic.Empty);
|
||||
rpc AbortMediaSync(generic.Empty) returns (generic.Empty);
|
||||
rpc SyncLogin(SyncLoginRequest) returns (SyncAuth);
|
||||
rpc SyncStatus(SyncAuth) returns (SyncStatusResponse);
|
||||
rpc SyncCollection(SyncAuth) returns (SyncCollectionResponse);
|
||||
rpc FullUpload(SyncAuth) returns (generic.Empty);
|
||||
rpc FullDownload(SyncAuth) returns (generic.Empty);
|
||||
rpc AbortSync(generic.Empty) returns (generic.Empty);
|
||||
}
|
||||
|
||||
message SyncAuth {
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::fmt::Write;
|
|||
use std::path::PathBuf;
|
||||
|
||||
use anki_io::write_file_if_changed;
|
||||
use anki_proto::codegen::RustMethods;
|
||||
use anki_proto::codegen::BackendMethod;
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use inflections::Inflect;
|
||||
|
@ -48,6 +48,7 @@ struct RustMethod {
|
|||
input_type: Option<String>,
|
||||
output_type: Option<String>,
|
||||
options: anki_proto::codegen::MethodOptions,
|
||||
service_name: String,
|
||||
}
|
||||
|
||||
impl RustMethod {
|
||||
|
@ -74,21 +75,21 @@ impl RustMethod {
|
|||
}
|
||||
|
||||
fn wants_abstract_backend_method(&self) -> bool {
|
||||
self.options.rust_methods() != RustMethods::CollectionAndAutoBackend
|
||||
self.service_name.starts_with("Backend")
|
||||
|| self.options.backend_method() == BackendMethod::Implement
|
||||
}
|
||||
|
||||
fn wants_abstract_collection_method(&self) -> bool {
|
||||
self.options.rust_methods() != RustMethods::BackendOnly
|
||||
!self.service_name.starts_with("Backend")
|
||||
}
|
||||
}
|
||||
|
||||
impl RustMethod {
|
||||
fn from_proto(method: prost_reflect::MethodDescriptor) -> Self {
|
||||
RustMethod {
|
||||
name: method.name().to_snake_case(),
|
||||
input_type: rust_type(method.input().full_name()),
|
||||
output_type: rust_type(method.output().full_name()),
|
||||
options: method.options().transcode_to().unwrap(),
|
||||
service_name: method.parent_service().name().to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +190,11 @@ fn render_collection_trait(service: &RustService, buf: &mut String) {
|
|||
}
|
||||
|
||||
fn render_backend_trait(service: &RustService, buf: &mut String) {
|
||||
let name = format!("Backend{}", service.name);
|
||||
let name = if !service.name.starts_with("Backend") {
|
||||
format!("Backend{}", service.name)
|
||||
} else {
|
||||
service.name.clone()
|
||||
};
|
||||
writeln!(buf, "pub trait {name} {{").unwrap();
|
||||
for method in &service.methods {
|
||||
if method.wants_abstract_backend_method() {
|
||||
|
|
Loading…
Reference in a new issue