-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
312 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import HTTP | ||
import .ProtoBuf: encode, decode, ProtoDecoder, ProtoEncoder | ||
|
||
export protobuf | ||
|
||
""" | ||
protobuf(request::HTTP.Request, type::Type{T}) :: T where {T} | ||
Decode a protobuf message from the body of an HTTP request. | ||
# Arguments | ||
- `request`: An HTTP request object containing the protobuf message in its body. | ||
- `type`: The type of the protobuf message to decode. | ||
# Returns | ||
- The decoded protobuf message of the specified type. | ||
""" | ||
function protobuf(request::HTTP.Request, type::Type{T}) :: T where {T} | ||
io = IOBuffer(request.body) | ||
return decode(ProtoDecoder(io), type) | ||
end | ||
|
||
|
||
""" | ||
protobuf(content::T, url::String, method::String = "POST") :: HTTP.Request where {T} | ||
Encode a protobuf message into the body of an HTTP request. | ||
# Arguments | ||
- `content`: The protobuf message to encode. | ||
- `url`: The URL to which the request will be sent. | ||
- `method`: The HTTP method for the request (default is "POST"). | ||
- `headers`: The HTTP headers for the request (default is an empty list). | ||
# Returns | ||
- An HTTP request object with the encoded protobuf message in its body. | ||
""" | ||
function protobuf(content::T, url::String; method = "GET", headers = []) :: HTTP.Request where {T} | ||
io = IOBuffer() | ||
encode(ProtoEncoder(io), content) | ||
body = take!(io) | ||
# Format the request | ||
request = HTTP.Request(method, url, headers, body) | ||
HTTP.setheader(request, "Content-Type" => "application/octet-stream") | ||
HTTP.setheader(request, "Content-Length" => string(sizeof(body))) | ||
return request | ||
end | ||
|
||
|
||
""" | ||
protobuf(content::T; status = 200, headers = []) :: HTTP.Response where {T} | ||
Encode a protobuf message into the body of an HTTP response. | ||
# Arguments | ||
- `content`: The protobuf message to encode. | ||
- `status`: The HTTP status code for the response (default is 200). | ||
- `headers`: The HTTP headers for the response (default is an empty list). | ||
# Returns | ||
- An HTTP response object with the encoded protobuf message in its body. | ||
""" | ||
function protobuf(content::T; status = 200, headers = []) :: HTTP.Response where {T} | ||
io = IOBuffer() | ||
encode(ProtoEncoder(io), content) | ||
body = take!(io) | ||
# Format the response | ||
response = HTTP.Response(status, headers, body = body) | ||
HTTP.setheader(response, "Content-Type" => "application/octet-stream") | ||
HTTP.setheader(response, "Content-Length" => string(sizeof(body))) | ||
return response | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
syntax = "proto3"; | ||
|
||
message Person { | ||
string name = 1; | ||
sint32 age = 2; | ||
} | ||
|
||
message People { | ||
repeated Person people = 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# Autogenerated using ProtoBuf.jl v1.0.15 on 2024-03-10T22:46:41.410 | ||
# original file: D:\Programming\JuliaProjects\oxygen-demo\src\people.proto (proto3 syntax) | ||
|
||
module people_pb | ||
|
||
import ProtoBuf as PB | ||
using ProtoBuf: OneOf | ||
using ProtoBuf.EnumX: @enumx | ||
|
||
export Person, People | ||
|
||
struct Person | ||
name::String | ||
age::Int32 | ||
end | ||
PB.default_values(::Type{Person}) = (;name = "", age = zero(Int32)) | ||
PB.field_numbers(::Type{Person}) = (;name = 1, age = 2) | ||
|
||
function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:Person}) | ||
name = "" | ||
age = zero(Int32) | ||
while !PB.message_done(d) | ||
field_number, wire_type = PB.decode_tag(d) | ||
if field_number == 1 | ||
name = PB.decode(d, String) | ||
elseif field_number == 2 | ||
age = PB.decode(d, Int32, Val{:zigzag}) | ||
else | ||
PB.skip(d, wire_type) | ||
end | ||
end | ||
return Person(name, age) | ||
end | ||
|
||
function PB.encode(e::PB.AbstractProtoEncoder, x::Person) | ||
initpos = position(e.io) | ||
!isempty(x.name) && PB.encode(e, 1, x.name) | ||
x.age != zero(Int32) && PB.encode(e, 2, x.age, Val{:zigzag}) | ||
return position(e.io) - initpos | ||
end | ||
function PB._encoded_size(x::Person) | ||
encoded_size = 0 | ||
!isempty(x.name) && (encoded_size += PB._encoded_size(x.name, 1)) | ||
x.age != zero(Int32) && (encoded_size += PB._encoded_size(x.age, 2, Val{:zigzag})) | ||
return encoded_size | ||
end | ||
|
||
struct People | ||
people::Vector{Person} | ||
end | ||
PB.default_values(::Type{People}) = (;people = Vector{Person}()) | ||
PB.field_numbers(::Type{People}) = (;people = 1) | ||
|
||
function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:People}) | ||
people = PB.BufferedVector{Person}() | ||
while !PB.message_done(d) | ||
field_number, wire_type = PB.decode_tag(d) | ||
if field_number == 1 | ||
PB.decode!(d, people) | ||
else | ||
PB.skip(d, wire_type) | ||
end | ||
end | ||
return People(people[]) | ||
end | ||
|
||
function PB.encode(e::PB.AbstractProtoEncoder, x::People) | ||
initpos = position(e.io) | ||
!isempty(x.people) && PB.encode(e, 1, x.people) | ||
return position(e.io) - initpos | ||
end | ||
function PB._encoded_size(x::People) | ||
encoded_size = 0 | ||
!isempty(x.people) && (encoded_size += PB._encoded_size(x.people, 1)) | ||
return encoded_size | ||
end | ||
end # module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
syntax = "proto3"; | ||
|
||
message MyMessage { | ||
sint32 a = 1; | ||
repeated string b = 2; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Autogenerated using ProtoBuf.jl v1.0.15 on 2024-02-27T23:51:29.590 | ||
# original file: D:\Programming\JuliaProjects\oxygen-demo\src\test.proto (proto3 syntax) | ||
|
||
module test_pb | ||
|
||
import ProtoBuf as PB | ||
using ProtoBuf: OneOf | ||
using ProtoBuf.EnumX: @enumx | ||
|
||
export MyMessage | ||
|
||
struct MyMessage | ||
a::Int32 | ||
b::Vector{String} | ||
end | ||
PB.default_values(::Type{MyMessage}) = (;a = zero(Int32), b = Vector{String}()) | ||
PB.field_numbers(::Type{MyMessage}) = (;a = 1, b = 2) | ||
|
||
function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:MyMessage}) | ||
a = zero(Int32) | ||
b = PB.BufferedVector{String}() | ||
while !PB.message_done(d) | ||
field_number, wire_type = PB.decode_tag(d) | ||
if field_number == 1 | ||
a = PB.decode(d, Int32, Val{:zigzag}) | ||
elseif field_number == 2 | ||
PB.decode!(d, b) | ||
else | ||
PB.skip(d, wire_type) | ||
end | ||
end | ||
return MyMessage(a, b[]) | ||
end | ||
|
||
function PB.encode(e::PB.AbstractProtoEncoder, x::MyMessage) | ||
initpos = position(e.io) | ||
x.a != zero(Int32) && PB.encode(e, 1, x.a, Val{:zigzag}) | ||
!isempty(x.b) && PB.encode(e, 2, x.b) | ||
return position(e.io) - initpos | ||
end | ||
function PB._encoded_size(x::MyMessage) | ||
encoded_size = 0 | ||
x.a != zero(Int32) && (encoded_size += PB._encoded_size(x.a, 1, Val{:zigzag})) | ||
!isempty(x.b) && (encoded_size += PB._encoded_size(x.b, 2)) | ||
return encoded_size | ||
end | ||
end # module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
module ProtobufTests | ||
|
||
using Test | ||
using HTTP | ||
using ProtoBuf | ||
using Oxygen: protobuf | ||
|
||
include("messages/people_pb.jl"); | ||
using .people_pb: People, Person | ||
|
||
include("messages/test_pb.jl"); | ||
using .test_pb: MyMessage | ||
|
||
@testset "Protobuf decoder test" begin | ||
message = MyMessage(-1, ["a", "b"]) | ||
req::HTTP.Request = protobuf(message, "/") | ||
|
||
decoded_msg = protobuf(req, MyMessage) | ||
|
||
@test decoded_msg isa MyMessage | ||
@test decoded_msg.a == -1 | ||
@test decoded_msg.b == ["a", "b"] | ||
end | ||
|
||
@testset "Protobuf People Decoder test" begin | ||
message = People([ | ||
Person("John Doe", 20), | ||
Person("Jane Doe", 25), | ||
Person("Alice", 30), | ||
Person("Bob", 35), | ||
Person("Charlie", 40) | ||
]) | ||
|
||
req::HTTP.Request = protobuf(message, "/", method="POST") | ||
|
||
decoded_msg = protobuf(req, People) | ||
|
||
@test decoded_msg isa People | ||
for person in decoded_msg.people | ||
@test person isa Person | ||
end | ||
end | ||
|
||
|
||
@testset "Protobuf encoder test" begin | ||
|
||
message = MyMessage(-1, ["a", "b"]) | ||
response = protobuf(message) | ||
|
||
@test response isa HTTP.Response | ||
@test response.status == 200 | ||
@test response.body isa Vector{UInt8} | ||
@test HTTP.header(response, "Content-Type") == "application/octet-stream" | ||
@test HTTP.header(response, "Content-Length") == string(sizeof(response.body)) | ||
end | ||
|
||
|
||
@testset "Protobuf People encoder test" begin | ||
message = People([ | ||
Person("John Doe", 20), | ||
Person("Jane Doe", 25), | ||
Person("Alice", 30), | ||
Person("Bob", 35), | ||
Person("Charlie", 40) | ||
]) | ||
|
||
response = protobuf(message) | ||
|
||
@test response isa HTTP.Response | ||
@test response.status == 200 | ||
@test response.body isa Vector{UInt8} | ||
@test HTTP.header(response, "Content-Type") == "application/octet-stream" | ||
@test HTTP.header(response, "Content-Length") == string(sizeof(response.body)) | ||
end | ||
|
||
|
||
end |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters