-
Notifications
You must be signed in to change notification settings - Fork 60
continue prost #286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
continue prost #286
Changes from all commits
e777fc9
c8bacbd
da8166f
8e32522
0ff5ede
5237576
23256d3
eadbd7b
735a10e
ce3c169
26b0146
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,4 +6,9 @@ Cargo.lock | |
| .idea | ||
| *.o | ||
| example/protocols/**/*.rs | ||
| !example/protocols/**/mod.rs | ||
| example2/protocols/**/*.rs | ||
| !example2/protocols/**/mod.rs | ||
| src/ttrpc.rs | ||
| example2/protocols/**/*.rs | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These |
||
| !example2/protocols/**/mod.rs | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,8 @@ description = "A Rust version of ttrpc." | |
| rust-version = "1.70" | ||
|
|
||
| [dependencies] | ||
| protobuf = { version = "3.1.0" } | ||
| prost = { version = "0.11", optional = true } | ||
| protobuf = {version = "3.1.0", optional = true} | ||
| libc = { version = "0.2.59", features = [ "extra_traits" ] } | ||
| nix = "0.26.2" | ||
| log = "0.4" | ||
|
|
@@ -34,11 +35,14 @@ tokio-vsock = { version = "0.7.0", optional = true } | |
| # lock home to avoid conflict with latest version | ||
| home = "=0.5.9" | ||
| protobuf-codegen = "3.1.0" | ||
| prost-build = { version = "0.13", optional = true } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor/dependencies: the runtime uses |
||
|
|
||
| [features] | ||
| default = ["sync"] | ||
| default = ["sync","rustprotobuf"] | ||
| async = ["async-trait", "async-stream", "tokio", "futures", "tokio-vsock"] | ||
| sync = [] | ||
| prost = ["dep:prost", "dep:prost-build"] | ||
| rustprotobuf = ["dep:protobuf"] | ||
|
|
||
| [package.metadata.docs.rs] | ||
| all-features = true | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| PROTOC ?= $(shell which protoc 2>/dev/null || echo $(HOME)/protoc/bin/protoc) | ||
|
|
||
| all: debug test | ||
|
|
||
| # | ||
|
|
@@ -21,12 +23,24 @@ build: debug | |
|
|
||
| .PHONY: test | ||
| test: | ||
| cargo test --all-features --verbose | ||
| ifeq ($OS,Windows_NT) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. GNU make parses |
||
| cargo test --features sync,async,rustprotobuf | ||
| else | ||
| # cargo test --all-features --verbose | ||
| cargo test --features sync,async,rustprotobuf | ||
| cargo test --no-default-features --features sync,async,prost | ||
| endif | ||
|
|
||
| .PHONY: check | ||
| check: | ||
| cargo fmt --all -- --check | ||
| cargo clippy --all-targets --all-features -- -D warnings | ||
| cargo clippy --all-targets --features sync,async -- -D warnings | ||
| # Skip prost check on Windows | ||
| ifeq ($(OS),Windows_NT) | ||
| @echo "Skipping prost check on Windows" | ||
| else | ||
| cargo clippy --all-targets --no-default-features --features sync,async,prost -- -D warnings | ||
| endif | ||
|
|
||
| .PHONY: check-all | ||
| check-all: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -138,3 +138,19 @@ cargo update | |
| cargo install --force --path . | ||
| ``` | ||
| 3. Build your project. | ||
|
|
||
| # ttrpc-rust with the Prost | ||
|
|
||
| The new version of the ttrpc-rust is built with the Prost crate, a modern | ||
| protobuf compiler written by Rust. There are certain different behaviors from | ||
| the Rust-protobuf version: | ||
|
|
||
| 1. The protoc should be installed. | ||
| 2. Enabling "prost" feature for the ttrpc-rust. | ||
| 3. The Rust files are named based on their package name, rather than the proto | ||
| filename, e.g. `ttrpc = { version = "1.0", features = ["prost"] }`. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This example enables |
||
| 4. Some variable names are different, e.g. for "cpu", "CPU" is generated by the | ||
| Rust-protobuf, and "Cpu" is genereated by the Prost. | ||
|
|
||
| The "example" is an example with the Rust-protobuf version, and the "example2" | ||
| is an example with the Prost version. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,11 @@ fn main() { | |
| let path: PathBuf = [out_dir.clone(), "mod.rs".to_string()].iter().collect(); | ||
| fs::write(path, "pub mod ttrpc;").unwrap(); | ||
|
|
||
| generate_ttrpc(&out_dir); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To get unified internal APIs which was defined in ttrpc.proto, how about keeping build script untouched? I think we can try to avoid so many condition compiling sentences like #[cfg(not(feature = "prost"))] in code.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right ,I think adding a transformation to the camel hump naming convention can reduce this conditional compilation code |
||
| } | ||
|
|
||
| #[cfg(not(feature = "prost"))] | ||
| fn generate_ttrpc(out_dir: &str) { | ||
| let customize = protobuf_codegen::Customize::default() | ||
| .gen_mod_rs(false) | ||
| .generate_accessors(true); | ||
|
|
@@ -20,3 +25,70 @@ fn main() { | |
| .run() | ||
| .expect("Codegen failed."); | ||
| } | ||
|
|
||
| #[cfg(feature = "prost")] | ||
| fn generate_ttrpc(out_dir: &str) { | ||
| let mut config = prost_build::Config::new(); | ||
| config | ||
| .out_dir(out_dir) | ||
| .compile_well_known_types() | ||
| .protoc_arg("--experimental_allow_proto3_optional") | ||
| .enum_attribute("Code", "#[allow(non_camel_case_types)]") | ||
| .compile_protos(&["src/ttrpc.proto"], &["src"]) | ||
| .expect("Codegen failed"); | ||
|
|
||
| // read ttrpc.rs | ||
| let ttrpc_path = format!("{}/ttrpc.rs", out_dir); | ||
| let content = fs::read_to_string(&ttrpc_path).expect("Failed to read ttrpc.rs"); | ||
|
|
||
| // define the enum value name pairs | ||
| let replacements = [ | ||
| ("Ok", "OK"), | ||
| ("Cancelled", "CANCELLED"), | ||
| ("Unknown", "UNKNOWN"), | ||
| ("InvalidArgument", "INVALID_ARGUMENT"), | ||
| ("DeadlineExceeded", "DEADLINE_EXCEEDED"), | ||
| ("NotFound", "NOT_FOUND"), | ||
| ("AlreadyExists", "ALREADY_EXISTS"), | ||
| ("PermissionDenied", "PERMISSION_DENIED"), | ||
| ("Unauthenticated", "UNAUTHENTICATED"), | ||
| ("ResourceExhausted", "RESOURCE_EXHAUSTED"), | ||
| ("FailedPrecondition", "FAILED_PRECONDITION"), | ||
| ("Aborted", "ABORTED"), | ||
| ("OutOfRange", "OUT_OF_RANGE"), | ||
| ("Unimplemented", "UNIMPLEMENTED"), | ||
| ("Internal", "INTERNAL"), | ||
| ("Unavailable", "UNAVAILABLE"), | ||
| ("DataLoss", "DATA_LOSS"), | ||
| ]; | ||
|
|
||
| // replace the enum value in the file | ||
| let mut modified_content = content.clone(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor/performance: please avoid rewriting Prost-generated Rust as text. This is coupled to Prost's formatting and performs many full-string replacement passes; |
||
|
|
||
| // replace the enum definition | ||
| for (pascal_case, upper_case) in &replacements { | ||
| // replace the enum definition line | ||
| let enum_pattern = format!(" {} = ", pascal_case); | ||
| let enum_replacement = format!(" {} = ", upper_case); | ||
| modified_content = modified_content.replace(&enum_pattern, &enum_replacement); | ||
|
|
||
| // replace the as_str_name function | ||
| let match_pattern = format!(" Self::{} => ", pascal_case); | ||
| let match_replacement = format!(" Self::{} => ", upper_case); | ||
| modified_content = modified_content.replace(&match_pattern, &match_replacement); | ||
|
|
||
| // replace the from_str_name function | ||
| let from_str_pattern = format!( | ||
| " \"{}\" => Some(Self::{})", | ||
| upper_case, pascal_case | ||
| ); | ||
| let from_str_replacement = format!( | ||
| " \"{}\" => Some(Self::{})", | ||
| upper_case, upper_case | ||
| ); | ||
| modified_content = modified_content.replace(&from_str_pattern, &from_str_replacement); | ||
| } | ||
|
|
||
| // write the modified content back to the file | ||
| fs::write(&ttrpc_path, modified_content).expect("Failed to write modified ttrpc.rs"); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| [package] | ||
| name = "ttrpc-codegen" | ||
| version = "1.0.0" | ||
| edition = "2021" | ||
| authors = ["The Ant Group Kata Team <kata@list.alibaba-inc.com>"] | ||
| license = "Apache-2.0" | ||
| keywords = ["codegen", "ttrpc", "protobuf"] | ||
| description = "Rust codegen for ttrpc using prost crate" | ||
| categories = ["network-programming", "development-tools::build-utils"] | ||
| repository = "https://github.com/containerd/ttrpc-rust/tree/master/codegen" | ||
| homepage = "https://github.com/containerd/ttrpc-rust/tree/master/codegen" | ||
| readme = "README.md" | ||
|
|
||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
|
||
| [dependencies] | ||
| prost = "0.11" | ||
| prost-types = "0.11" | ||
| prost-build = "0.11" | ||
| proc-macro2 = "1.0" | ||
| quote = "1.0" | ||
| anyhow = "^1.0" | ||
| lazy_static = "1.4" | ||
| regex = "1.7" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| all: debug test | ||
|
|
||
| # | ||
| # Build | ||
| # | ||
|
|
||
| .PHONY: debug | ||
| debug: | ||
| cargo build --verbose --all-targets | ||
|
|
||
| .PHONY: release | ||
| release: | ||
| cargo build --release | ||
|
|
||
| .PHONY: build | ||
| build: debug | ||
|
|
||
| # | ||
| # Tests and linters | ||
| # | ||
|
|
||
| .PHONY: test | ||
| test: | ||
| cargo test --verbose | ||
|
|
||
| .PHONY: check | ||
| check: | ||
| cargo fmt --all -- --check | ||
| cargo clippy --all-targets --all-features -- -D warnings | ||
|
|
||
| .PHONY: deps | ||
| deps: | ||
| rustup update stable | ||
| rustup default stable | ||
| rustup component add rustfmt clippy |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Ttrpc-rust Codegen | ||
|
|
||
| ## Getting started | ||
|
|
||
| Please ensure that the protoc has been installed on your local environment. Then | ||
| write the following code into "build.rs". | ||
|
|
||
| ```rust | ||
| let mut protos = vec![ | ||
| "protocols/protos/health.proto", | ||
| "protocols/protos/agent.proto", | ||
| "protocols/protos/oci.proto", | ||
| ]; | ||
|
|
||
| let includes = vec!["protocols/protos"]; | ||
|
|
||
| let codegen = CodegenBuilder::new() | ||
| .set_out_dir(&"protocols/sync") | ||
| .set_protos(&protos) | ||
| .set_includes(&includes) | ||
| .set_serde(true) | ||
| .set_async_mode(AsyncMode::None) | ||
| .set_generate_service(true) | ||
| .build() | ||
| .unwrap(); | ||
| codegen.generate().unwrap(); | ||
| ``` | ||
|
|
||
| Add ttrpc-codegen to "build-dependencies" section in "Cargo.toml". | ||
|
|
||
| ```toml | ||
| [build-dependencies] | ||
| ttrpc-codegen = "1.0" | ||
| ``` |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing
shell: bashmakes this multi-command step use PowerShell on Windows, where an earlier native-command failure can be hidden by a later successful command. Keepshell: bash, or split the commands into separate steps with explicit failure handling.