mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
use protobuf for python/rust bridge
If we go ahead with betterproto on the Python side, it will mean bumping the minimum Python dependency to 3.7.
This commit is contained in:
parent
e893294ee4
commit
252a0cb54f
16 changed files with 649 additions and 46 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -3,15 +3,18 @@
|
|||
*\#
|
||||
*~
|
||||
.*.swp
|
||||
.DS_Store
|
||||
.build
|
||||
.coverage
|
||||
.DS_Store
|
||||
.mypy_cache
|
||||
.pytype
|
||||
__pycache__
|
||||
anki/buildhash.py
|
||||
anki/proto
|
||||
aqt/forms
|
||||
locale
|
||||
rs/ankirs/src/proto.rs
|
||||
rs/target
|
||||
tools/runanki.system
|
||||
ts/node_modules
|
||||
web/deckbrowser.js
|
||||
|
@ -20,4 +23,3 @@ web/overview.js
|
|||
web/reviewer-bottom.js
|
||||
web/reviewer.js
|
||||
web/webview.js
|
||||
rs/target
|
||||
|
|
20
Makefile
20
Makefile
|
@ -96,6 +96,11 @@ RUST_TOOLCHAIN := $(shell cat rs/rust-toolchain)
|
|||
rustup component add clippy-preview --toolchain $(RUST_TOOLCHAIN)
|
||||
@touch $@
|
||||
|
||||
# Protobuf
|
||||
######################
|
||||
|
||||
PROTODEPS := $(wildcard proto/*.proto)
|
||||
|
||||
# Typescript source
|
||||
######################
|
||||
|
||||
|
@ -105,12 +110,12 @@ JSDEPS := $(patsubst ts/src/%.ts, web/%.js, $(TSDEPS))
|
|||
# Rust source
|
||||
######################
|
||||
|
||||
RSDEPS := $(wildcard rs/*/src/*.rs)
|
||||
RSDEPS := $(shell find rs -type f | grep -v target)
|
||||
|
||||
# Building
|
||||
######################
|
||||
|
||||
BUILDDEPS := .build/ui .build/js .build/rs
|
||||
BUILDDEPS := .build/ui .build/js .build/rs .build/py-proto
|
||||
|
||||
.build/ui: $(RUNREQS) $(shell find designer -type f)
|
||||
./tools/build_ui.sh
|
||||
|
@ -120,10 +125,14 @@ BUILDDEPS := .build/ui .build/js .build/rs
|
|||
(cd ts && npm run build)
|
||||
@touch $@
|
||||
|
||||
.build/rs: .build/rust-deps $(RUNREQS) $(RSDEPS)
|
||||
.build/rs: .build/rust-deps $(RUNREQS) $(RSDEPS) $(PROTODEPS)
|
||||
(cd rs/pybridge && maturin develop $(RUSTARGS))
|
||||
@touch $@
|
||||
|
||||
.build/py-proto: $(RUNREQS) $(PROTODEPS)
|
||||
protoc -I proto --python_betterproto_out=anki/proto proto/bridge.proto
|
||||
@touch $@
|
||||
|
||||
.PHONY: build clean
|
||||
|
||||
build: $(BUILDDEPS)
|
||||
|
@ -147,6 +156,9 @@ run: build
|
|||
.PHONY: check
|
||||
check: rs-test rs-fmt rs-clippy py-mypy py-test py-fmt py-imports py-lint ts-fmt
|
||||
|
||||
.PHONY: fix
|
||||
fix: fix-py-fmt fix-py-imports fix-rs-fmt fix-ts-fmt
|
||||
|
||||
# Checking python
|
||||
######################
|
||||
|
||||
|
@ -156,7 +168,7 @@ PYCHECKDEPS := $(BUILDDEPS) .build/py-check-reqs $(shell find anki aqt -name '*.
|
|||
mypy anki aqt
|
||||
@touch $@
|
||||
|
||||
.build/pytest: $(PYCHECKDEPS) $(wildcard tests/*.py)
|
||||
.build/py-test: $(PYCHECKDEPS) $(wildcard tests/*.py)
|
||||
./tools/tests.sh
|
||||
@touch $@
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ from anki.lang import _, ngettext
|
|||
from anki.media import MediaManager
|
||||
from anki.models import ModelManager
|
||||
from anki.notes import Note
|
||||
from anki.rsbridge import RSBridge
|
||||
from anki.sched import Scheduler as V1Scheduler
|
||||
from anki.schedv2 import Scheduler as V2Scheduler
|
||||
from anki.sound import stripSounds
|
||||
|
@ -84,8 +85,12 @@ class _Collection:
|
|||
ls: int
|
||||
conf: Dict[str, Any]
|
||||
_undo: List[Any]
|
||||
rust: RSBridge
|
||||
|
||||
def __init__(self, db: DB, server: bool = False, log: bool = False) -> None:
|
||||
def __init__(
|
||||
self, db: DB, server: bool = False, log: bool = False, rust: RSBridge = None
|
||||
) -> None:
|
||||
self.rust = rust
|
||||
self._debugLog = log
|
||||
self.db = db
|
||||
self.path = db._path
|
||||
|
|
|
@ -1,10 +1,37 @@
|
|||
import _ankirs # pytype: disable=import-error
|
||||
import betterproto
|
||||
|
||||
from anki.proto import proto as pb
|
||||
|
||||
|
||||
class BridgeException(Exception):
|
||||
def __str__(self) -> str:
|
||||
err: pb.BridgeError = self.args[0] # pylint: disable=unsubscriptable-object
|
||||
(kind, obj) = betterproto.which_one_of(err, "value")
|
||||
if kind == "invalid_input":
|
||||
return f"invalid input: {obj.info}"
|
||||
else:
|
||||
return f"unhandled error: {err} {obj}"
|
||||
|
||||
|
||||
class RSBridge:
|
||||
def __init__(self):
|
||||
self._bridge = _ankirs.Bridge()
|
||||
assert self._bridge.cmd("") == "test"
|
||||
|
||||
def _run_command(self, input: pb.BridgeInput) -> pb.BridgeOutput:
|
||||
input_bytes = bytes(input)
|
||||
output_bytes = self._bridge.command(input_bytes)
|
||||
output = pb.BridgeOutput().parse(output_bytes)
|
||||
(kind, obj) = betterproto.which_one_of(output, "value")
|
||||
if kind == "error":
|
||||
raise BridgeException(obj)
|
||||
else:
|
||||
return output
|
||||
|
||||
def plus_one(self, num: int) -> int:
|
||||
input = pb.BridgeInput(plus_one=pb.PlusOneIn(num=num))
|
||||
output = self._run_command(input)
|
||||
return output.plus_one.num
|
||||
|
||||
|
||||
bridge = RSBridge()
|
||||
|
|
|
@ -12,6 +12,7 @@ from anki.collection import _Collection
|
|||
from anki.consts import *
|
||||
from anki.db import DB
|
||||
from anki.lang import _
|
||||
from anki.rsbridge import RSBridge
|
||||
from anki.stdmodels import (
|
||||
addBasicModel,
|
||||
addBasicTypingModel,
|
||||
|
@ -26,6 +27,8 @@ def Collection(
|
|||
path: str, lock: bool = True, server: bool = False, log: bool = False
|
||||
) -> _Collection:
|
||||
"Open a new or existing collection. Path must be unicode."
|
||||
bridge = RSBridge()
|
||||
assert bridge.plus_one(5) == 6
|
||||
assert path.endswith(".anki2")
|
||||
path = os.path.abspath(path)
|
||||
create = not os.path.exists(path)
|
||||
|
@ -46,7 +49,7 @@ def Collection(
|
|||
db.execute("pragma journal_mode = wal")
|
||||
db.setAutocommit(False)
|
||||
# add db to col and do any remaining upgrades
|
||||
col = _Collection(db, server, log)
|
||||
col = _Collection(db, server, log, rust=bridge)
|
||||
if ver < SCHEMA_VERSION:
|
||||
_upgrade(col, ver)
|
||||
elif ver > SCHEMA_VERSION:
|
||||
|
|
36
proto/bridge.proto
Normal file
36
proto/bridge.proto
Normal file
|
@ -0,0 +1,36 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
|
||||
message Empty {}
|
||||
|
||||
message BridgeInput {
|
||||
oneof value {
|
||||
PlusOneIn plus_one = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message BridgeOutput {
|
||||
oneof value {
|
||||
BridgeError error = 1;
|
||||
PlusOneOut plus_one = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message BridgeError {
|
||||
oneof value {
|
||||
InvalidInputError invalid_input = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message InvalidInputError {
|
||||
string info = 1;
|
||||
}
|
||||
|
||||
message PlusOneIn {
|
||||
int32 num = 1;
|
||||
}
|
||||
|
||||
message PlusOneOut {
|
||||
int32 num = 1;
|
||||
}
|
|
@ -8,3 +8,4 @@ jsonschema
|
|||
psutil; sys_platform == "win32"
|
||||
distro; sys_platform != "win32" and sys_platform != "darwin"
|
||||
typing
|
||||
betterproto[compiler]
|
||||
|
|
449
rs/Cargo.lock
generated
449
rs/Cargo.lock
generated
|
@ -12,6 +12,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ankirs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"failure",
|
||||
"prost",
|
||||
"prost-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
|
@ -19,14 +25,118 @@ version = "0.1.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
|
||||
dependencies = [
|
||||
"backtrace-sys",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-sys"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"iovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "c2-chacha"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
|
||||
[[package]]
|
||||
name = "failure"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"failure_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "failure_derive"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -35,9 +145,18 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -57,9 +176,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b714fc08d0961716390977cdff1536234415ac37b509e34e5a983def8340fb75"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
"unindent",
|
||||
]
|
||||
|
||||
|
@ -80,9 +199,27 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2869bf972e998977b1cb87e60df70341d48e48dca0823f534feb91ea44adaf9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -103,12 +240,27 @@ version = "0.2.66"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.10"
|
||||
|
@ -135,20 +287,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -157,13 +333,66 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-build"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck",
|
||||
"itertools",
|
||||
"log",
|
||||
"multimap",
|
||||
"petgraph",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11"
|
||||
dependencies = [
|
||||
"failure",
|
||||
"itertools",
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"syn 0.15.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pybridge"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ankirs",
|
||||
"pyo3",
|
||||
]
|
||||
|
||||
|
@ -194,9 +423,9 @@ version = "0.8.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f6e56fb3e97b344a8f87d036f94578399402c6b75949de6270cd07928f790b1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -205,10 +434,19 @@ version = "0.8.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97452dcdf5941627ebc5c06664a07821fc7fc88d7515f02178193a8ebe316468"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2 1.0.6",
|
||||
"pyo3-derive-backend",
|
||||
"quote",
|
||||
"syn",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -217,9 +455,56 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2 1.0.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||
dependencies = [
|
||||
"c2-chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.1"
|
||||
|
@ -238,6 +523,21 @@ version = "0.6.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.2"
|
||||
|
@ -259,9 +559,9 @@ version = "1.0.104"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -281,15 +581,52 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.11",
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rand",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -301,6 +638,18 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
|
@ -318,3 +667,41 @@ name = "version_check"
|
|||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
|
||||
dependencies = [
|
||||
"failure",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
|
@ -3,3 +3,11 @@ name = "ankirs"
|
|||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
authors = ["Ankitects Pty Ltd and contributors"]
|
||||
|
||||
[dependencies]
|
||||
failure = "0.1.6"
|
||||
prost = "0.5.0"
|
||||
bytes = "0.4"
|
||||
|
||||
[build-dependencies]
|
||||
prost-build = "0.5.0"
|
||||
|
|
7
rs/ankirs/build.rs
Normal file
7
rs/ankirs/build.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
use prost_build;
|
||||
|
||||
fn main() {
|
||||
// avoid default OUT_DIR for now, for code completion
|
||||
std::env::set_var("OUT_DIR", "src");
|
||||
prost_build::compile_protos(&["../../proto/bridge.proto"], &["../../proto/"]).unwrap();
|
||||
}
|
84
rs/ankirs/src/bridge.rs
Normal file
84
rs/ankirs/src/bridge.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use crate::err::{AnkiError, Result};
|
||||
use crate::proto as pt;
|
||||
use crate::proto::bridge_input::Value;
|
||||
use prost::Message;
|
||||
|
||||
pub struct Bridge {}
|
||||
|
||||
impl Default for Bridge {
|
||||
fn default() -> Self {
|
||||
Bridge {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert an Anki error to a protobuf error.
|
||||
impl std::convert::From<AnkiError> for pt::BridgeError {
|
||||
fn from(err: AnkiError) -> Self {
|
||||
use pt::bridge_error::Value as V;
|
||||
let value = match err {
|
||||
AnkiError::InvalidInput { info } => V::InvalidInput(pt::InvalidInputError { info }),
|
||||
};
|
||||
|
||||
pt::BridgeError { value: Some(value) }
|
||||
}
|
||||
}
|
||||
|
||||
// Convert an Anki error to a protobuf output.
|
||||
impl std::convert::From<AnkiError> for pt::bridge_output::Value {
|
||||
fn from(err: AnkiError) -> Self {
|
||||
pt::bridge_output::Value::Error(err.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Bridge {
|
||||
pub fn new() -> Bridge {
|
||||
Bridge::default()
|
||||
}
|
||||
|
||||
/// Decode a request, process it, and return the encoded result.
|
||||
pub fn run_command_bytes(&mut self, req: &[u8]) -> Vec<u8> {
|
||||
let mut buf = vec![];
|
||||
|
||||
let req = match pt::BridgeInput::decode(req) {
|
||||
Ok(req) => req,
|
||||
Err(_e) => {
|
||||
// unable to decode
|
||||
let err = AnkiError::invalid_input("couldn't decode bridge request");
|
||||
let output = pt::BridgeOutput {
|
||||
value: Some(err.into()),
|
||||
};
|
||||
output.encode(&mut buf).expect("encode failed");
|
||||
return buf;
|
||||
}
|
||||
};
|
||||
|
||||
let resp = self.run_command(req);
|
||||
resp.encode(&mut buf).expect("encode failed");
|
||||
buf
|
||||
}
|
||||
|
||||
fn run_command(&self, input: pt::BridgeInput) -> pt::BridgeOutput {
|
||||
let oval = if let Some(ival) = input.value {
|
||||
match self.run_command_inner(ival) {
|
||||
Ok(output) => output,
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
} else {
|
||||
AnkiError::invalid_input("unrecognized bridge input value").into()
|
||||
};
|
||||
|
||||
pt::BridgeOutput { value: Some(oval) }
|
||||
}
|
||||
|
||||
fn run_command_inner(&self, ival: pt::bridge_input::Value) -> Result<pt::bridge_output::Value> {
|
||||
use pt::bridge_output::Value as OValue;
|
||||
Ok(match ival {
|
||||
Value::PlusOne(input) => OValue::PlusOne(self.plus_one(input)?),
|
||||
})
|
||||
}
|
||||
|
||||
fn plus_one(&self, input: pt::PlusOneIn) -> Result<pt::PlusOneOut> {
|
||||
let num = input.num + 1;
|
||||
Ok(pt::PlusOneOut { num })
|
||||
}
|
||||
}
|
16
rs/ankirs/src/err.rs
Normal file
16
rs/ankirs/src/err.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
pub use failure::{Error, Fail};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, AnkiError>;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum AnkiError {
|
||||
#[fail(display = "invalid input: {}", info)]
|
||||
InvalidInput { info: String },
|
||||
}
|
||||
|
||||
// error helpers
|
||||
impl AnkiError {
|
||||
pub(crate) fn invalid_input<S: Into<String>>(s: S) -> AnkiError {
|
||||
AnkiError::InvalidInput { info: s.into() }
|
||||
}
|
||||
}
|
|
@ -1 +1,4 @@
|
|||
mod proto;
|
||||
|
||||
pub mod bridge;
|
||||
pub mod err;
|
||||
|
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||
edition = "2018"
|
||||
authors = ["Ankitects Pty Ltd and contributors"]
|
||||
|
||||
[dependencies]
|
||||
ankirs = { path = "../ankirs" }
|
||||
|
||||
[dependencies.pyo3]
|
||||
version = "0.8.0"
|
||||
features = ["extension-module"]
|
||||
|
|
|
@ -1,19 +1,27 @@
|
|||
use pyo3::exceptions;
|
||||
use ankirs::bridge::Bridge as RustBridge;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyBytes;
|
||||
|
||||
#[pyclass]
|
||||
struct Bridge {}
|
||||
struct Bridge {
|
||||
bridge: RustBridge,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl Bridge {
|
||||
#[new]
|
||||
fn init(obj: &PyRawObject) {
|
||||
obj.init({ Bridge {} });
|
||||
obj.init({
|
||||
Bridge {
|
||||
bridge: Default::default(),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn cmd(&mut self, _request: String) -> PyResult<String> {
|
||||
Ok("test".to_string())
|
||||
.map_err(|e: std::io::Error| exceptions::Exception::py_err(format!("{:?}", e)))
|
||||
fn command(&mut self, py: Python, input: &PyBytes) -> PyResult<PyObject> {
|
||||
let out_bytes = self.bridge.run_command_bytes(input.as_bytes());
|
||||
let out_obj = PyBytes::new(py, &out_bytes);
|
||||
Ok(out_obj.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
rs/rustfmt.toml
Normal file
1
rs/rustfmt.toml
Normal file
|
@ -0,0 +1 @@
|
|||
ignore = ["proto.rs"]
|
Loading…
Reference in a new issue