Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ members = [
]

[workspace.package]
version = "0.2.3"
version = "0.2.4"
edition = "2021"
license = "MIT"
repository = "https://github.com/blockscout/actix-prost"
Expand Down
23 changes: 18 additions & 5 deletions actix-prost-build/src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
rc::Rc,
};

use crate::helpers::extract_type_from_option;
use crate::helpers::{extract_type_from_option, try_construct_external_type_path};
use proc_macro2::{Ident, TokenStream};
use prost_build::Service;
use prost_reflect::{
Expand Down Expand Up @@ -443,10 +443,23 @@ impl ConversionsGenerator {

match extract_type_from_option(&f.ty) {
Some(Type::Path(ty)) => {
let ty = ty.path.segments.first()?;
let rust_struct_name = self.messages.get(&ty.ident.to_string())?.ident.clone();
let new_struct_name =
self.build_internal_nested_struct(m_type, &rust_struct_name, res);
let maybe_local_message = ty
.path
.segments
.first()
.and_then(|s| self.messages.get(&s.ident.to_string()));

let new_struct_name = if let Some(item_struct) = maybe_local_message {
let rust_struct_name = item_struct.ident.clone();
let new_struct_name =
self.build_internal_nested_struct(m_type, &rust_struct_name, res);
quote!(#new_struct_name)
} else if let Some(path) = try_construct_external_type_path(&ty.path) {
quote!(#path)
} else {
return None;
};

let convert = &self.convert_prefix;
let (ty, conversion) = match convert_field {
Some(ConvertFieldOptions { required: true, .. }) => {
Expand Down
39 changes: 32 additions & 7 deletions actix-prost-build/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
use syn::{GenericArgument, Path, PathArguments, PathSegment};

pub fn extract_type_from_option(ty: &syn::Type) -> Option<&syn::Type> {
fn extract_type_path(ty: &syn::Type) -> Option<&Path> {
match *ty {
syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path),
_ => None,
}
}

fn extract_option_segment(path: &Path) -> Option<&PathSegment> {
let idents_of_path = path.segments.iter().fold(String::new(), |mut acc, v| {
acc.push_str(&v.ident.to_string());
Expand Down Expand Up @@ -35,3 +28,35 @@ pub fn extract_type_from_option(ty: &syn::Type) -> Option<&syn::Type> {
_ => None,
})
}

pub fn try_construct_external_type_path(path: &Path) -> Option<Path> {
let idents_of_path = path.segments.iter().fold(String::new(), |mut acc, v| {
acc.push_str(&v.ident.to_string());
acc.push('|');
acc
});

// ignore conventional external imported types
let ignore_segments = ["super|google|protobuf|"];
if ignore_segments.iter().any(|s| idents_of_path.contains(s)) {
return None;
}

if !idents_of_path.starts_with("super|") {
return None;
}

let mut new_path = path.clone();

let ty = new_path.segments.last_mut()?;
ty.ident = quote::format_ident!("{}Internal", ty.ident);

Some(new_path)
}

fn extract_type_path(ty: &syn::Type) -> Option<&Path> {
match *ty {
syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path),
_ => None,
}
}
3 changes: 3 additions & 0 deletions tests/proto/conversions.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";
package conversions;

import "convert_options.proto";
import "errors.proto";

option go_package = "github.com/blockscout/actix-prost/tests";

Expand Down Expand Up @@ -95,6 +96,8 @@ message ConversionsResponse {
string response_naive_datetime = 8 [ (convert_options.convert) = { type : "chrono::NaiveDateTime" } ];
string response_uuid = 9 [ (convert_options.convert) = { type : "uuid::Uuid" } ];
string response_decimal = 10 [ (convert_options.convert) = { type : "rust_decimal::Decimal" } ];

errors.ErrorResponse error = 11;
}


Expand Down
9 changes: 8 additions & 1 deletion tests/proto/errors.proto
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
syntax = "proto3";
package errors;

import "convert_options.proto";

option go_package = "github.com/blockscout/actix-prost/tests";

service ErrorsRPC { rpc Error(ErrorRequest) returns (ErrorResponse); }
Expand All @@ -11,4 +13,9 @@ message ErrorRequest {
string message = 3;
}

message ErrorResponse {}
message ErrorResponse {
option (convert_options.derive) = { name: "serde::Serialize" };
option (convert_options.derive) = { name: "serde::Deserialize" };
option (convert_options.derive) = { name: "PartialEq" };
option (convert_options.derive) = { name: "Eq" };
}
7 changes: 0 additions & 7 deletions tests/proto/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,12 @@ message OneOfs {
}
}

// message Google {
// google.protobuf.Timestamp foo = 1;
// google.protobuf.Any bar = 2;
// }

message Complex {
Scalars scalars = 1;
Enums enums = 2;
Repeated repeated = 3;
Maps maps = 4;
OneOfs oneofs = 5;
// Google google = 6;
}

service TypesRPC {
Expand All @@ -59,6 +53,5 @@ service TypesRPC {
rpc RepeatedRPC(Repeated) returns (Repeated);
rpc MapsRPC(Maps) returns (Maps);
rpc OneOfsRPC(OneOfs) returns (OneOfs);
// rpc GoogleRPC(Google) returns (Google);
rpc ComplexRPC(Complex) returns (Complex);
}
2 changes: 0 additions & 2 deletions tests/proto/types.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ produces:
paths:
/types/complex:
post:
summary: rpc GoogleRPC(Google) returns (Google);
operationId: TypesRPC_ComplexRPC
responses:
"200":
Expand Down Expand Up @@ -183,7 +182,6 @@ definitions:
$ref: '#/definitions/typesMaps'
oneofs:
$ref: '#/definitions/typesOneOfs'
title: Google google = 6;
typesEnums:
type: object
properties:
Expand Down
1 change: 1 addition & 0 deletions tests/src/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ impl ConversionsRpc for ConversionsServer {
response_naive_datetime: internal_request.naive_datetime,
response_uuid: internal_request.uuid_field,
response_decimal: internal_request.decimal_field,
error: None,
};

let response = ConversionsResponse::try_convert(internal_response)
Expand Down
4 changes: 4 additions & 0 deletions tests/src/proto/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ pub struct ConversionsResponse {
pub response_uuid: ::prost::alloc::string::String,
#[prost(string, tag = "10")]
pub response_decimal: ::prost::alloc::string::String,
#[prost(message, optional, tag = "11")]
pub error: ::core::option::Option<super::errors::ErrorResponse>,
}
#[actix_prost_macros::serde]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
Expand Down Expand Up @@ -409,6 +411,7 @@ pub struct ConversionsResponseInternal {
pub response_naive_datetime: chrono::NaiveDateTime,
pub response_uuid: uuid::Uuid,
pub response_decimal: rust_decimal::Decimal,
pub error: ::core::option::Option<super::errors::ErrorResponseInternal>,
}
impl convert_trait::TryConvert<ConversionsResponseInternal> for ConversionsResponse {
fn try_convert(from: ConversionsResponseInternal) -> Result<Self, String> {
Expand All @@ -430,6 +433,7 @@ impl convert_trait::TryConvert<ConversionsResponseInternal> for ConversionsRespo
response_decimal: convert_trait::TryConvert::try_convert(
from.response_decimal,
)?,
error: convert_trait::TryConvert::try_convert(from.error)?,
})
}
}
Expand Down
4 changes: 4 additions & 0 deletions tests/src/proto/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ impl convert_trait::TryConvert<ErrorRequest> for ErrorRequestInternal {
})
}
}
#[derive(serde::Serialize)]
#[derive(serde::Deserialize)]
#[derive(PartialEq)]
#[derive(Eq)]
#[derive(Clone, Debug)]
pub struct ErrorResponseInternal {}
impl convert_trait::TryConvert<ErrorResponseInternal> for ErrorResponse {
Expand Down
4 changes: 0 additions & 4 deletions tests/src/proto/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ pub struct Complex {
pub repeated: ::core::option::Option<Repeated>,
#[prost(message, optional, tag = "4")]
pub maps: ::core::option::Option<Maps>,
/// Google google = 6;
#[prost(message, optional, tag = "5")]
pub oneofs: ::core::option::Option<OneOfs>,
}
Expand Down Expand Up @@ -175,7 +174,6 @@ pub mod types_rpc_actix {
pub repeated: ::core::option::Option<Repeated>,
#[prost(message, optional, tag = "4")]
pub maps: ::core::option::Option<Maps>,
/// Google google = 6;
#[prost(message, optional, tag = "5")]
pub oneofs: ::core::option::Option<OneOfs>,
}
Expand Down Expand Up @@ -762,7 +760,6 @@ pub mod types_rpc_client {
req.extensions_mut().insert(GrpcMethod::new("types.TypesRPC", "OneOfsRPC"));
self.inner.unary(req, path, codec).await
}
/// rpc GoogleRPC(Google) returns (Google);
pub async fn complex_rpc(
&mut self,
request: impl tonic::IntoRequest<super::Complex>,
Expand Down Expand Up @@ -822,7 +819,6 @@ pub mod types_rpc_server {
&self,
request: tonic::Request<super::OneOfs>,
) -> std::result::Result<tonic::Response<super::OneOfs>, tonic::Status>;
/// rpc GoogleRPC(Google) returns (Google);
async fn complex_rpc(
&self,
request: tonic::Request<super::Complex>,
Expand Down
Loading