### Run ZIO Route Guide Example Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/routeguide/README.md Execute the ZIO version of the Route Guide example using sbt. ```bash sbt "examples/runMain proteus.examples.routeguide.zio.RouteGuideExample" ``` -------------------------------- ### Run FS2 Route Guide Example Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/routeguide/README.md Execute the FS2 version of the Route Guide example using sbt. ```bash sbt "examples/runMain proteus.examples.routeguide.fs2.RouteGuideExample" ``` -------------------------------- ### Proteus Deriver and Codec Setup Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Initial setup for Proteus, deriving a ProtobufDeriver and a ProtobufCodec for the Movie type. ```scala import proteus.* given ProtobufDeriver = ProtobufDeriver given ProtobufCodec[Movie] = ProtobufCodec.derived[Movie] ``` -------------------------------- ### Start gRPC Server Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Build and start the gRPC server using the generated ServerServiceDefinition. This involves configuring the server port and adding the service. ```scala import io.grpc.ServerBuilder ServerBuilder.forPort(8080).addService(service).build().start() ``` -------------------------------- ### Implement Greeter Server Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/greeter/README.md Sets up and builds the gRPC server for the Greeter service. It binds the RPC method to its implementation and starts the server on a specified port. ```scala class GreeterServer(port: Int) { val service = ServerService(using DirectServerBackend) .rpc(sayHelloRpc, sayHello) .build(greeterService) val server = ServerBuilder.forPort(port).addService(service).build() } ``` -------------------------------- ### Markdown Output Example Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md An example of the markdown output format, detailing proto changes with severity indicators and specific modifications within files and messages. ```markdown ## Proto changes (3) - 🔴 1 error - 🟡 1 warning - 🔵 1 info ### `user.proto` #### `User` - 🔴 **FieldRemoved** — field 'email' removed - 🟡 **FieldAdded** — field 'phone' added - 🔵 **CommentChanged** — comment changed on 'User' ``` -------------------------------- ### Server Interceptor Example Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Example of creating a ServerContextInterceptor to transform the request context by extracting an auth-token from metadata. ```APIDOC ## ServerInterceptor Interceptors allow modification of the `Context` type or the `Unary`/`Streaming` wrapper types. ### ServerContextInterceptor A specific trait to transform only the context. #### Example ```scala val interceptor = new ServerContextInterceptor[[A] =>> A, [A] =>> A, RequestResponseMetadata, String] { def transformContext(context: RequestResponseMetadata): String = { context.requestMetadata.get(Metadata.Key.of("auth-token", Metadata.ASCII_STRING_MARSHALLER)) } } ``` This interceptor changes the `Context` type from `RequestResponseMetadata` to `String`, extracting the `auth-token` from request metadata for the logic function `(Request, String) => Response`. ### Usage ```scala val backend = DirectServerBackend(interceptor) val service = ServerService(using backend) ``` ``` -------------------------------- ### Install proteus-diff on Linux Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Downloads the latest proteus-diff binary for Linux x86_64, makes it executable, and displays help information. ```bash curl -sL https://github.com/ghostdogpr/proteus/releases/latest/download/proteus-diff-linux-x86_64 > proteus-diff && chmod +x proteus-diff && ./proteus-diff --help ``` -------------------------------- ### Route Guide Scala Definitions Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/routeguide/README.md Defines the case classes for Protobuf messages and the Proteus RPC definitions for the Route Guide service. ```scala case class Point(latitude: Int, longitude: Int) derives ProtobufCodec case class Rectangle(lo: Point, hi: Point) derives ProtobufCodec case class Feature(name: String, location: Point) derives ProtobufCodec case class RouteNote(location: Point, message: String) derives ProtobufCodec case class RouteSummary(pointCount: Int, featureCount: Int, distance: Int, elapsedTime: Int) derives ProtobufCodec val getFeatureRpc = Rpc.unary[Point, Feature]("GetFeature") val listFeaturesRpc = Rpc.serverStreaming[Rectangle, Feature]("ListFeatures") val recordRouteRpc = Rpc.clientStreaming[Point, RouteSummary]("RecordRoute") val routeChatRpc = Rpc.bidiStreaming[RouteNote, RouteNote]("RouteChat") val routeGuideService = Service("routeguide", "RouteGuide") .rpc(getFeatureRpc) .rpc(listFeaturesRpc) .rpc(recordRouteRpc) .rpc(routeChatRpc) ``` -------------------------------- ### JSON output example Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md An example of the JSON output format produced by proteus-diff, detailing detected schema changes with their type, severity, and path. ```json [ {"type": "FieldRemoved", "severity": "error", "path": ["user.proto", "User"], "message": "user.proto.User: field 'email' removed"}, {"type": "FieldAdded", "severity": "warning", "path": ["user.proto", "User"], "message": "user.proto.User: field 'phone' added"} ] ``` -------------------------------- ### Route Guide Protobuf Definitions Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/routeguide/README.md Defines the messages and service for the Route Guide gRPC application, including Point, Feature, Rectangle, RouteNote, and RouteSummary, along with the four RPC methods. ```protobuf syntax = "proto3"; package routeguide; service RouteGuide { rpc GetFeature (Point) returns (Feature) {} rpc ListFeatures (Rectangle) returns (stream Feature) {} rpc RecordRoute (stream Point) returns (RouteSummary) {} rpc RouteChat (stream RouteNote) returns (stream RouteNote) {} } message Point { int32 latitude = 1; int32 longitude = 2; } message Feature { string name = 1; Point location = 2; } message Rectangle { Point lo = 1; Point hi = 2; } message RouteSummary { int32 point_count = 1; int32 feature_count = 2; int32 distance = 3; int32 elapsed_time = 4; } message RouteNote { Point location = 1; string message = 2; } ``` -------------------------------- ### Install proteus-diff on macOS Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Downloads the latest proteus-diff binary for macOS (Apple Silicon/Intel), makes it executable, and displays help information. It automatically detects the architecture. ```bash ARCH=$(uname -m | sed 's/arm64/aarch64/') && curl -sL https://github.com/ghostdogpr/proteus/releases/latest/download/proteus-diff-macos-${ARCH} > proteus-diff && chmod +x proteus-diff && ./proteus-diff --help ``` -------------------------------- ### Server Context Interceptor Example Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Implement a ServerContextInterceptor to transform the request context. This example extracts an 'auth-token' from metadata, changing the context type to String for the direct backend. ```scala val interceptor = new ServerContextInterceptor[[A] =>> A, [A] =>> A, RequestResponseMetadata, String] { def transformContext(context: RequestResponseMetadata): String = context.requestMetadata.get(Metadata.Key.of("auth-token", Metadata.ASCII_STRING_MARSHALLER)) } ``` -------------------------------- ### Machine-Readable Output for Custom Reporters Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Generate output in JSON format for integration with custom reporting tools. This example filters for errors using jq. ```bash proteus-diff old/ new/ -f json | jq '.[] | select(.severity == "error")' ``` -------------------------------- ### Chimney Transformation for ReleaseStatus Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Example of a Chimney transformer for handling the ReleaseStatus type, specifically converting an 'Empty' value to Unreleased(None) for backward compatibility. ```scala given PartialTransformer[proto.migration.ReleaseStatus, ReleaseStatus] = PartialTransformer( _.value .intoPartial[ReleaseStatus] .withSealedSubtypeHandledPartial[ proto.migration.ReleaseStatus.Value.Empty.type ](_ => Result.fromValue(ReleaseStatus.Unreleased(None))) .transform ) ``` -------------------------------- ### Inline Oneof Field Example Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Demonstrates how to encode a oneof type as a single field within the parent message, using the `Inline` flag. ```protobuf message Example { int32 field = 1; oneof address { Email email = 2; Phone phone = 3; } } ``` -------------------------------- ### Derive Circe Encoder from ProtobufCodec Source: https://github.com/ghostdogpr/proteus/blob/main/docs/json-support.md Add the proteus-json dependency to your build.sbt. Import proteus.json.* and ensure implicit `ProtobufDeriver`, `Registry`, and `Options` are in scope to automatically derive Circe `Encoder` instances from `ProtobufCodec` instances. This example shows encoding a case class to JSON. ```scala import io.circe.syntax.* import proteus.* import proteus.json.* given ProtobufDeriver = ProtobufDeriver given Registry = Registry.empty given Options = Options.default case class HelloRequest(name: String) derives ProtobufCodec val json = HelloRequest("world").asJson.noSpaces println(json) // {"name":"world"} ``` -------------------------------- ### Nested Oneof Type Example Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Illustrates encoding a oneof type as a separate, nested type within the parent message, using the `Nested` flag. ```protobuf message Example { message Address { oneof value { Email email = 1; Phone phone = 2; } } int32 field = 1; Address address = 2; } ``` -------------------------------- ### Register Custom Circe Encoder with Registry Source: https://github.com/ghostdogpr/proteus/blob/main/docs/json-support.md Use `Registry.empty.add[T](encoder)` to register a custom Circe encoder for a specific type `T`. This overrides the default derived encoder, allowing for custom JSON representations. For example, encoding a `MyId` case class as a plain JSON string. ```scala import io.circe.* case class MyId(value: String) derives ProtobufCodec given Registry = Registry.empty.add[MyId](Encoder[String].contramap(_.value)) ``` -------------------------------- ### Implement Greeter Client Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/greeter/README.md Establishes a connection to the gRPC server and creates a client stub for the SayHello RPC. Uses ManagedChannelBuilder for connection and DirectClientBackend for communication. ```scala class GreeterClient(host: String, port: Int) { val channel: ManagedChannel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build() val backend = DirectClientBackend(channel) val sayHelloClient = backend.client(sayHelloRpc, greeterService) } ``` -------------------------------- ### gRPC Client Initialization Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Set up a gRPC client by building a ManagedChannel and then creating a DirectClientBackend. This backend is used to create a client for a specific RPC and service. ```scala import io.grpc.* import proteus.client.* val channel = ManagedChannelBuilder .forAddress("localhost", 8080) .usePlaintext() .build() val backend = DirectClientBackend(channel) val sayHelloClient = backend.client(sayHelloRpc, greeterService) ``` -------------------------------- ### Compare git refs and filesystem paths Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Demonstrates various ways to compare proto schemas using git references and filesystem paths, including comparing branches, commits, and the working tree. ```bash proteus-diff main . ``` ```bash proteus-diff HEAD ./proto ``` ```bash proteus-diff main HEAD ``` ```bash proteus-diff HEAD~1 HEAD ``` ```bash proteus-diff v0.1.0 v0.2.0 ``` -------------------------------- ### gRPC Client Implementation Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Demonstrates how to create a gRPC client using Proteus, including channel creation and client instantiation for different RPC types. ```APIDOC ## Client Implementation Creating a client involves providing a backend, which requires a `Channel` instance. ### Backend Creation ```scala import io.grpc.* import proteus.client.* val channel = ManagedChannelBuilder .forAddress("localhost", 8080) .usePlaintext() .build() val backend = DirectClientBackend(channel) ``` ### Client Instantiation ```scala val sayHelloClient = backend.client(sayHelloRpc, greeterService) ``` #### Return Types based on RPC Type: - Unary: `Request => Response` (with Direct backend) - Client Streaming: `Streaming[Request] => Response` (with Direct backend) - Server Streaming: `Request => Streaming[Response]` (with Direct backend) - Bidirectional Streaming: `Streaming[Request] => Streaming[Response]` (with Direct backend) ### Example Usage ```scala sayHelloClient(HelloRequest("Pierre")) // HelloReply("Hello, Pierre!") ``` ``` -------------------------------- ### Compare proto versions with proteus-diff Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proto-file-generation.md Use the `proteus-diff` tool to compare .proto files between versions and detect breaking changes before deployment. ```bash proteus-diff proto/main proto/pr ``` -------------------------------- ### Show All Changes Including Info-Level Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Display all detected changes, including those at the info level, which might be useful for detailed reviews. ```bash proteus-diff old/ new/ -s info ``` -------------------------------- ### gRPC Client with Metadata Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Shows how to create a gRPC client that can send and receive metadata, using the `clientWithMetadata` method. ```APIDOC ## Client with Metadata Use `clientWithMetadata` to create a client that handles metadata. ### Function Shape: - Unary: `(Request, Metadata) => (Response, Metadata)` (with Direct backend) - Client Streaming: `(Streaming[Request], Metadata) => (Response, Metadata)` (with Direct backend) - Server Streaming: `(Request, Metadata) => Streaming[Response]` (with Direct backend) - Bidirectional Streaming: `(Streaming[Request], Metadata) => Streaming[Response]` (with Direct backend) ### Example Usage ```scala val sayHelloClientWithMetadata = backend.clientWithMetadata(sayHelloRpc, greeterService) val requestMetadata = new Metadata() requestMetadata.put(Metadata.Key.of("auth-token", Metadata.ASCII_STRING_MARSHALLER), "1234567890") sayHelloClientWithMetadata(HelloRequest("Pierre"), requestMetadata)._1 // HelloReply("Hello, Pierre!") ``` ``` -------------------------------- ### Compare schemas with compatibility modes Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Compares two proto files using a specific compatibility mode ('wire', 'source', or 'strictest'). The 'strictest' mode is the default. ```bash proteus-diff old.proto new.proto -m wire ``` -------------------------------- ### Creating a Direct Server Backend with Interceptor Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Instantiate a DirectServerBackend by passing the created interceptor. This backend will then use the interceptor for all incoming requests. ```scala val backend = DirectServerBackend(interceptor) val service = ServerService(using backend) //.rpc(...).build(...) ``` -------------------------------- ### Generated Protobuf Definition Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/greeter/README.md The Protobuf definition for the Greeter service, including the SayHello RPC method and its request/reply messages. This file is typically generated by the Protobuf compiler. ```protobuf syntax = "proto3"; package examples; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ``` -------------------------------- ### Compare two proto files Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Compares two individual .proto files to detect schema changes. ```bash proteus-diff old.proto new.proto ``` -------------------------------- ### Run sbt proto generation task Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proto-file-generation.md Execute the defined sbt task to generate the .proto files. This can be automated in CI pipelines. ```bash sbt generateProtos ``` -------------------------------- ### Rendering Initial Protobuf Schema Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Code to render the Protobuf schema for the Movie type using Proteus. This step helps identify unsupported types. ```scala println(Dependency("migration", "proto").add[Movie].render(Nil)) ``` -------------------------------- ### Add top-level options to .proto files Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proto-file-generation.md The `render` and `renderToFile` methods accept a list of `ProtoIR.TopLevelOption` to be added at the top of the generated .proto file. ```scala val options = List( ProtoIR.TopLevelOption("java_package", "com.example") ) println(entities.render(options)) ``` -------------------------------- ### Define Greeter Messages and Service Source: https://github.com/ghostdogpr/proteus/blob/main/examples/src/main/scala/proteus/examples/greeter/README.md Defines the request and reply messages for the Greeter service and the RPC method signature. Requires ProtobufCodec derivation for message serialization. ```scala case class HelloRequest(name: String) derives ProtobufCodec case class HelloReply(message: String) derives ProtobufCodec val sayHelloRpc = Rpc.unary[HelloRequest, HelloReply]("SayHello") val greeterService = Service("examples", "Greeter").rpc(sayHelloRpc) ``` -------------------------------- ### Compare two directories of proto files Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Recursively compares all .proto files within two directories to detect schema changes. ```bash proteus-diff old/ new/ ``` -------------------------------- ### Implement Server Logic with Context Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Implement server logic using `rpcWithContext` to access call context such as request metadata. The logic function signature adapts to include the context parameter. ```scala def processHello(request: HelloRequest, ctx: RequestResponseMetadata): HelloReply = { println(s"Request metadata: ${ctx.requestMetadata}") HelloReply(s"Hello, ${request.name}!") } val service = ServerService(using DirectServerBackend) .rpcWithContext(sayHelloRpc, processHello) .build(greeterService) ``` -------------------------------- ### Define a Service Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Define a gRPC service by providing a package name and service name, then adding the defined RPCs using the `rpc` method. ```scala val greeterService = Service("examples", "Greeter").rpc(sayHelloRpc) ``` -------------------------------- ### Render a gRPC service to .proto Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proto-file-generation.md Proteus can render entire gRPC services. The `Service` and `Rpc` case classes are used to define the service and its methods. ```scala import proteus.* given ProtobufDeriver = ProtobufDeriver // your deriver instance case class HelloRequest(name: String) derives ProtobufCodec case class HelloResponse(message: String) derives ProtobufCodec val helloRpc = Rpc.unary[HelloRequest, HelloResponse]("Hello") val helloService = Service("examples", "Greeter").rpc(helloRpc) println(helloService.render(Nil)) ``` -------------------------------- ### Render a single type to .proto Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proto-file-generation.md Use the `Dependency` case class to bundle related types and render them into a single .proto file. Adding a type automatically includes its dependencies. ```scala import proteus.* given ProtobufDeriver = ProtobufDeriver // your deriver instance case class Address(street: String, city: String) derives ProtobufCodec case class Person(name: String, address: Address) derives ProtobufCodec val entities = Dependency("entities", "com.example").add[Person] println(entities.render(Nil)) ``` -------------------------------- ### gRPC Client with Metadata Support Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Create a client that supports sending and receiving metadata. The clientWithMetadata function returns a function with a signature that includes Metadata. ```scala val sayHelloClientWithMetadata = backend.clientWithMetadata(sayHelloRpc, greeterService) ``` -------------------------------- ### Configure sbt task for proto generation Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proto-file-generation.md Integrate proto file generation into your build process by defining an sbt task that runs your main class responsible for generation. ```scala lazy val generateProtos = taskKey[Unit]("Generate proto files") generateProtos := (Compile / runMain).toTask(" examples.Protogen").value ``` -------------------------------- ### Render Custom Schema Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Verify the generated Protobuf schema after applying codec transformations by rendering the custom codec. ```scala println(codec.render()) // syntax = "proto3"; // // message Order { // repeated Item items = 1; // } // // message Item { // string id = 1; // int32 count = 2; // } ``` -------------------------------- ### Generated Protobuf Schema with Custom Codecs Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md The resulting Protobuf schema after integrating custom codecs for OffsetDateTime and Duration, showing the updated structure. ```proto syntax = "proto3"; package proto; message Movie { int32 id = 1; string title = 2; repeated Genre genres = 3; int32 duration = 4; ReleaseStatus released_status = 5; } enum Genre { COMEDY = 0; DRAMA = 1; HORROR = 2; } message ReleaseStatus { oneof value { Released released = 1; Unreleased unreleased = 2; } } message Released { int64 release_date = 1; } message Unreleased { optional int64 planned_release_date = 1; } ``` -------------------------------- ### Implement Server Logic with DirectServerBackend Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Implement the server logic for an RPC using a specific backend. For DirectServerBackend, the logic function for a unary RPC is Request => Response. Streaming is not supported. ```scala import proteus.server.* val service = ServerService(using DirectServerBackend) .rpc(sayHelloRpc, request => HelloReply(s"Hello, ${request.name}!")) .build(greeterService) ``` -------------------------------- ### Render Protobuf Schema for a Case Class Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Generate and print the Protobuf schema associated with the derived codec for the `Person` case class. This shows the structure that will be used for serialization. ```scala println(codec.render()) // syntax = "proto3"; // // message Person { // string name = 1; // int32 age = 2; // } // ``` -------------------------------- ### Create a Custom Codec with Transformations Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Use the `.transform` method on a derived codec to map between your original Scala type and a Protobuf-specific type. Provide functions to convert to and from the Protobuf type. ```scala val codec: ProtobufCodec[Order] = ProtobufCodec .derived[Proto.Order](using ProtobufDeriver) .transform[Order]( proto => Order(proto.items.map(i => i.id -> i.count).toMap), order => Proto.Order(order.items.map((id, count) => Proto.Item(id, count)).toList) ) ``` -------------------------------- ### Derive Protobuf Codec using `derives` Keyword Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Use the `derives` keyword on a case class to automatically create a `ProtobufCodec` instance that is always in scope. This simplifies codec retrieval. ```scala case class Person(name: String, age: Int) derives ProtobufCodec ``` -------------------------------- ### Making a Unary RPC Call Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Execute a unary RPC call using the created client. The direct backend simplifies the call signature to Request => Response. ```scala sayHelloClient(HelloRequest("Pierre")) // HelloReply("Hello, Pierre!") ``` -------------------------------- ### Define Request and Response Case Classes Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Define case classes for requests and responses, deriving ProtobufCodec instances. Ensure a ProtobufDeriver instance is in scope for automatic codec derivation. ```scala given ProtobufDeriver = ProtobufDeriver // your deriver instance case class HelloRequest(name: String) derives ProtobufCodec case class HelloReply(message: String) derives ProtobufCodec ``` -------------------------------- ### Wire-Only Compatibility Check Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Perform a compatibility check focusing solely on the wire format, which is beneficial for consumers who only interact with the binary representation. ```bash proteus-diff old/ new/ -m wire ``` -------------------------------- ### Making an RPC Call with Metadata Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Invoke an RPC call using the metadata-enabled client. This involves creating a Metadata object, populating it with key-value pairs, and passing it along with the request. ```scala val requestMetadata = new Metadata() requestMetadata.put(Metadata.Key.of("auth-token", Metadata.ASCII_STRING_MARSHALLER), "1234567890") sayHelloClientWithMetadata(HelloRequest("Pierre"), requestMetadata)._1 // HelloReply("Hello, Pierre!") ``` -------------------------------- ### Add Proteus gRPC Dependency Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Add the Proteus gRPC dependency to your build.sbt file. Optional dependencies are available for specific backends like ZIO, fs2, and Ox. ```scala "com.github.ghostdogpr" %% "proteus-grpc" % "@VERSION@" // optional, only if you use these backends "com.github.ghostdogpr" %% "proteus-grpc-zio" % "@VERSION@" // zio backend "com.github.ghostdogpr" %% "proteus-grpc-fs2" % "@VERSION@" // fs2 backend "com.github.ghostdogpr" %% "proteus-grpc-ox" % "@VERSION@" // ox backend (requires JDK 21+) ``` -------------------------------- ### Stricter Policy: Fail on Warnings Too Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Configure proteus-diff to fail not only on breaking changes but also on warnings for a stricter policy. ```bash proteus-diff old/ new/ --fail-on warning ``` -------------------------------- ### Derive a Protobuf Codec for a Case Class Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Derive a Protobuf codec for the `Person` case class. This requires a `ProtobufDeriver` instance in scope, which is provided by default. ```scala import proteus.* given ProtobufDeriver = ProtobufDeriver val codec = ProtobufCodec.derived[Person] ``` -------------------------------- ### Generate Markdown Output Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Use the `-f markdown` flag to produce output suitable for platforms like GitHub or GitLab, commonly used in PR comments. ```bash proteus-diff main HEAD -f markdown ``` -------------------------------- ### Encode and Decode a Case Class Instance Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Use the derived Protobuf codec to encode a `Person` instance into an `Array[Byte]` and then decode it back. Asserts that the decoded instance matches the original. ```scala val person = Person("John Doe", 30) val encoded = codec.encode(person) val decoded = codec.decode(encoded) assert(decoded == person) ``` -------------------------------- ### Define an RPC Source: https://github.com/ghostdogpr/proteus/blob/main/docs/grpc-services.md Define an RPC using the Rpc case class, specifying the request and response types and the RPC name. The Rpc class supports unary, clientStreaming, serverStreaming, and bidiStreaming patterns. ```scala val sayHelloRpc = Rpc.unary[HelloRequest, HelloReply]("SayHello") ``` -------------------------------- ### Define a Scala Case Class Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Create a simple Scala case class that will be encoded and decoded into Protobuf format. Proteus can automatically derive codecs for such structures. ```scala case class Person(name: String, age: Int) ``` -------------------------------- ### Force git ref resolution Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Uses the 'git:' prefix to ensure a reference is treated as a git ref, overriding filesystem path resolution if a file or directory shares the same name. ```bash proteus-diff git:main ./proto ``` -------------------------------- ### Registering Custom Codecs with Deriver Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Updates the ProtobufDeriver to include the custom codecs for OffsetDateTime and Duration. ```scala given ProtobufDeriver = ProtobufDeriver .instance(timeCodec) .instance(durationCodec) ``` -------------------------------- ### Protobuf Schema Definition Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Defines the Protobuf message structure for Movie, including its fields, genres, and release status. This is the initial schema used with ScalaPB. ```proto syntax = "proto3"; package proto; import "scalapb/scalapb.proto"; option (scalapb.options) = { preserve_unknown_fields: false }; message Movie { reserved 2; int32 id = 1; repeated Genre genres = 3; string title = 4; int32 duration = 5; ReleaseStatus released_status = 6; } enum Genre { GENRE_COMEDY = 0; GENRE_DRAMA = 1; GENRE_HORROR = 2; } message ReleaseStatus { message Released { int64 release_date = 1; } message Unreleased { optional int64 planned_release_date = 1; } oneof value { Released released = 1; Unreleased unreleased = 2; } } ``` -------------------------------- ### Enable Derivation Flag AutoPrefixEnums Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Configure Protobuf schema derivation globally by enabling flags. `AutoPrefixEnums` automatically prefixes enum members with the enum's type name. ```scala import proteus.ProtobufDeriver.DerivationFlag val deriver = ProtobufDeriver.enable(DerivationFlag.AutoPrefixEnums) ``` -------------------------------- ### Generate JSON output Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Generates machine-consumable output in JSON format for detailed analysis of schema changes. ```bash proteus-diff old.proto new.proto -f json ``` -------------------------------- ### Enable Proteus Derivation Flags Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Enable AutoPrefixEnums for enum value prefixes and NestedOneOf for nesting oneof types. These flags are crucial for schema compatibility. ```scala import proteus.ProtobufDeriver.DerivationFlag.* given ProtobufDeriver = ProtobufDeriver .enable(AutoPrefixEnums) .enable(NestedOneOf) // continued ``` -------------------------------- ### Per-Team Severity Policy: Source Mode Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md In source mode, this command allows specific changes, like renaming fields, to be treated as informational rather than errors, based on a per-team policy. ```bash proteus-diff old/ new/ -m source -o source.FieldRenamed=info ``` -------------------------------- ### Retrieve In-Scope Protobuf Codec Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Once a codec is derived using the `derives` keyword, it can be accessed directly using `ProtobufCodec[Person]`. This codec can then be used for encoding, decoding, and rendering. ```scala val codec = ProtobufCodec[Person] ``` -------------------------------- ### Add Proteus Dependency to build.sbt Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Include the Proteus core module in your sbt project by adding this dependency to your `build.sbt` file. Replace `@VERSION@` with the desired version. ```scala "com.github.ghostdogpr" %% "proteus-core" % "@VERSION@" ``` -------------------------------- ### Render dependent types to .proto Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proto-file-generation.md Dependencies can depend on other dependencies. This will replace the types from the depended-on dependency with an import statement in the generated .proto file. ```scala val common = Dependency("common", "com.example").add[Address] val entitiesWithDependency = entities.dependsOn(common) println(entitiesWithDependency.render(Nil)) ``` -------------------------------- ### Severity Override Configuration Source: https://github.com/ghostdogpr/proteus/blob/main/docs/proteus-diff.md Configure custom severity levels for specific change types in different modes using the `-o` flag. This allows teams to align Proteus's change detection with their specific requirements. ```bash proteus-diff old.proto new.proto \ -o wire.FieldRemoved=info \ -o source.FieldRenamed=warning ``` -------------------------------- ### Configure JSON Encoding Options Source: https://github.com/ghostdogpr/proteus/blob/main/docs/json-support.md Modify the JSON encoding behavior by providing a custom `Options` instance. The `formatMapEntriesAsKeyValuePairs` option controls how map entries are represented in JSON. When true, map entries are encoded as an array of objects with explicit `key` and `value` fields. ```scala given Options = Options(formatMapEntriesAsKeyValuePairs = true) ``` -------------------------------- ### Derive Schema using `derives` Keyword Source: https://github.com/ghostdogpr/proteus/blob/main/docs/getting-started.md Add `derives Schema` to a case class, enum, or sealed trait to automatically create a `Schema` instance in its companion object. This improves compile-time efficiency by making the schema readily available. ```scala import zio.blocks.schema.* case class Person(name: String, age: Int) derives Schema ``` -------------------------------- ### Custom Codec for Duration Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Defines a custom ProtobufCodec for Duration, transforming it to and from an Int (int32 in Protobuf) to handle time durations. ```scala lazy val durationCodec: ProtobufCodec[Duration] = ProtobufCodec .derived[Int] .transform[Duration](Duration.ofMillis, _.toMillis.toInt) ``` -------------------------------- ### Scala Domain Entities Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Defines the Scala case classes and enums corresponding to the Protobuf schema. Includes domain types for Movie, Genre, and ReleaseStatus. ```scala import java.time.{Duration, OffsetDateTime} case class Movie( id: Int, title: String, genres: List[Genre], duration: Duration, releasedStatus: ReleaseStatus ) enum Genre { case Comedy, Drama, Horror } enum ReleaseStatus { case Released(releaseDate: OffsetDateTime) case Unreleased(plannedReleaseDate: Option[OffsetDateTime]) } ``` -------------------------------- ### Define Custom Protobuf Schema Types Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Define Scala case classes that mirror the desired Protobuf schema structure when the default generation is insufficient. These types are used in codec transformations. ```scala object Proto { case class Item(id: String, count: Int) case class Order(items: List[Item]) } ``` -------------------------------- ### Custom Codec for OffsetDateTime Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Defines a custom ProtobufCodec for OffsetDateTime, transforming it to and from a Long (int64 in Protobuf) to handle temporal data. ```scala import java.time.* lazy val timeCodec: ProtobufCodec[OffsetDateTime] = ProtobufCodec .derived[Long] .transform[OffsetDateTime]( millis => OffsetDateTime.ofInstant( Instant.ofEpochMilli(millis), ZoneOffset.UTC ), _.toInstant().toEpochMilli() ) ``` -------------------------------- ### Override Default Deriver with Custom Codec Instance Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Create a new deriver instance that uses your custom codec for a specific type. This ensures that the custom codec is used whenever this deriver is applied. ```scala val deriver = ProtobufDeriver.instance(codec) ``` -------------------------------- ### Set Default Value for Oneof Field Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Configure a default value for a oneof field in 'ReleaseStatus' to handle missing fields gracefully. This transforms an empty oneof into a specific state, like 'Unreleased(None)', ensuring backward compatibility. ```scala given Schema[ReleaseStatus] = Schema.derived[ReleaseStatus].defaultValue(ReleaseStatus.Unreleased(None)) ``` -------------------------------- ### Reserve Field Index in Protobuf Schema Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Reserve a specific field index (e.g., 2) for a message type like 'Movie' using modifiers. This is necessary for backward compatibility when fields are added or reordered. ```scala import proteus.Modifiers.* import zio.blocks.schema.* given Schema[Movie] = Schema.derived[Movie] given ProtobufDeriver = ProtobufDeriver .modifier[Movie](reserved(2)) // continued ``` -------------------------------- ### Assign Field Index Using Modifier Source: https://github.com/ghostdogpr/proteus/blob/main/docs/migrating-to-proteus.md Assign a specific field index (e.g., 4) to a field like 'title' in the 'Movie' message using modifiers. This helps manage field order for backward compatibility without altering the original case class. ```scala given ProtobufDeriver = ProtobufDeriver .modifier[Movie]("title", reserved(4)) // continued ``` -------------------------------- ### Derive Enum with AutoPrefixEnums Flag Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Demonstrates the effect of the `AutoPrefixEnums` derivation flag on an enum. Enum members are prefixed with the enum's type name in the generated Protobuf schema. ```scala enum Status { case Active, Inactive, Pending } val deriver = ProtobufDeriver.enable(DerivationFlag.AutoPrefixEnums) println(ProtobufCodec.derived[Status](using deriver).render()) ``` -------------------------------- ### Apply Multiple Modifiers Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Combine multiple modifiers in a single call to rename a type and add a comment, or to rename a field and mark it as deprecated. This streamlines the customization process. ```scala val deriver = ProtobufDeriver .modifier[Person](rename("User"), comment("A user record")) .modifier[Person]("name", rename("full_name"), deprecated) ``` -------------------------------- ### Apply Modifiers to Multiple Fields Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Use the `field(...)` helper to apply modifiers to several fields of the same type simultaneously. Term names are validated at compile time. ```scala val deriver = ProtobufDeriver.modifier[Person]( field("name", rename("full_name")), field("age", comment("Age in years")) ) ``` -------------------------------- ### Rename Protobuf Field Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Modify a specific field within a case class to have a different name in the Protobuf schema. This allows for schema evolution or adherence to different naming conventions. ```scala import proteus.Modifiers.* val deriver = ProtobufDeriver.modifier[Person]("name", rename("full_name")) println(ProtobufCodec.derived[Person](using deriver).render()) ``` ```protobuf syntax = "proto3"; message Person { string full_name = 1; int32 age = 2; } ``` -------------------------------- ### Rename Protobuf Message Type Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Apply a modifier to rename a case class in the Protobuf schema. This is useful when the desired Protobuf message name differs from the Scala case class name. ```scala import proteus.Modifiers.* val deriver = ProtobufDeriver.modifier[Person](rename("User")) println(ProtobufCodec.derived[Person](using deriver).render()) ``` ```protobuf syntax = "proto3"; message User { string name = 1; int32 age = 2; } ``` -------------------------------- ### Nest Type in Specific Ancestor with nestedIn Source: https://github.com/ghostdogpr/proteus/blob/main/docs/customization.md Use `nestedIn[A]` to define a type within a specific ancestor message `A`, rather than its direct parent. References from outside `A` are rewritten to their fully-qualified form. Ensure the target ancestor is reachable. ```scala import proteus.Modifiers.* case class Item(value: String) derives Schema case class Basket(item: Item) derives Schema case class Order(basket: Basket, item: Item) derives Schema val deriver = ProtobufDeriver.modifier[Item](nestedIn[Order]) println(ProtobufCodec.derived[Order](using deriver).render()) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.