|
| 1 | +# Protozoa Example Project |
| 2 | + |
| 3 | +This example project demonstrates the usage of the Protozoa Protocol Buffer library for Gleam. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Protozoa is a Protocol Buffer compiler and runtime library for Gleam that supports all 27 Google Protocol Buffer well-known types and provides complete encode/decode functionality. |
| 8 | + |
| 9 | +## What's Demonstrated |
| 10 | + |
| 11 | +This example showcases: |
| 12 | + |
| 13 | +### ✅ Core Protocol Buffer Features |
| 14 | +- **Basic Types**: `int32`, `string`, `bool`, `bytes`, `repeated` fields |
| 15 | +- **Enums**: User roles with proper encoding/decoding |
| 16 | +- **Oneof Fields**: Union types with multiple data variants |
| 17 | +- **Well-Known Types**: `Timestamp`, `StringValue`, and other Google well-known types |
| 18 | + |
| 19 | +### ✅ Advanced Features |
| 20 | +- **Message Nesting**: Complex message structures |
| 21 | +- **Type Safety**: Full Gleam type safety with generated types |
| 22 | +- **Encoding/Decoding**: Bidirectional serialization with proper error handling |
| 23 | + |
| 24 | +## Files Structure |
| 25 | + |
| 26 | +``` |
| 27 | +example/ |
| 28 | +├── src/ |
| 29 | +│ ├── proto/ |
| 30 | +│ │ └── simple.proto # Protocol Buffer definitions |
| 31 | +│ ├── generated/ |
| 32 | +│ │ └── proto.gleam # Auto-generated Gleam code |
| 33 | +│ └── simple_example.gleam # Main example application |
| 34 | +├── test/ |
| 35 | +│ └── simple_test.gleam # Test suite |
| 36 | +└── README.md # This file |
| 37 | +``` |
| 38 | + |
| 39 | +## Protocol Buffer Definitions |
| 40 | + |
| 41 | +### User Message |
| 42 | +Demonstrates basic types, enums, repeated fields, and well-known types: |
| 43 | + |
| 44 | +```proto |
| 45 | +message User { |
| 46 | + int32 id = 1; |
| 47 | + string name = 2; |
| 48 | + string email = 3; |
| 49 | + google.protobuf.Timestamp created_at = 4; |
| 50 | + bool is_active = 5; |
| 51 | + UserRole role = 6; |
| 52 | + repeated string tags = 7; |
| 53 | + google.protobuf.StringValue bio = 8; |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +### SimpleMessage with Oneof |
| 58 | +Demonstrates union types (oneof fields): |
| 59 | + |
| 60 | +```proto |
| 61 | +message SimpleMessage { |
| 62 | + string id = 1; |
| 63 | + |
| 64 | + oneof data { |
| 65 | + string text_data = 2; |
| 66 | + int64 numeric_data = 3; |
| 67 | + bytes binary_data = 4; |
| 68 | + } |
| 69 | + |
| 70 | + string description = 5; |
| 71 | + bool enabled = 6; |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +## Running the Example |
| 76 | + |
| 77 | +### Prerequisites |
| 78 | +- Gleam >= 1.5.0 |
| 79 | +- Protozoa library |
| 80 | + |
| 81 | +### Generate Code |
| 82 | +```bash |
| 83 | +# Generate Gleam code from proto files |
| 84 | +gleam run -m protozoa src/proto/simple.proto src/generated/ |
| 85 | +``` |
| 86 | + |
| 87 | +### Run the Example |
| 88 | +```bash |
| 89 | +gleam run -m simple_example |
| 90 | +``` |
| 91 | + |
| 92 | +Expected output: |
| 93 | +``` |
| 94 | +🚀 Protozoa Simple Example |
| 95 | +========================= |
| 96 | +👤 Created user: Alice (alice@example.com) |
| 97 | +📦 Encoded user data successfully |
| 98 | +💬 Created simple message: msg_001 |
| 99 | +✅ Successfully decoded message: msg_001 |
| 100 | + Text data: Hello, World! |
| 101 | +✅ Simple example completed! |
| 102 | +``` |
| 103 | + |
| 104 | +### Run Tests |
| 105 | +```bash |
| 106 | +gleam run -m gleeunit -- --module simple_test |
| 107 | +``` |
| 108 | + |
| 109 | +All tests should pass: |
| 110 | +``` |
| 111 | +3 tests, no failures |
| 112 | +``` |
| 113 | + |
| 114 | +## Generated Code Features |
| 115 | + |
| 116 | +The generated `proto.gleam` file includes: |
| 117 | + |
| 118 | +### Type Definitions |
| 119 | +- **Union Types**: For oneof fields with proper Gleam algebraic data types |
| 120 | +- **Record Types**: For messages with named fields |
| 121 | +- **Enum Types**: For protocol buffer enums |
| 122 | + |
| 123 | +### Encoding Functions |
| 124 | +- `encode_user(user: User) -> BitArray` |
| 125 | +- `encode_simplemessage(message: SimpleMessage) -> BitArray` |
| 126 | +- `encode_timestamp(timestamp: Timestamp) -> BitArray` |
| 127 | + |
| 128 | +### Decoding Functions |
| 129 | +- `decode_user(data: BitArray) -> Result(User, List(DecodeError))` |
| 130 | +- `decode_simplemessage(data: BitArray) -> Result(SimpleMessage, List(DecodeError))` |
| 131 | +- `decode_timestamp(data: BitArray) -> Result(Timestamp, List(DecodeError))` |
| 132 | + |
| 133 | +### Well-Known Types Support |
| 134 | +The generated code includes full support for Google's Protocol Buffer well-known types: |
| 135 | +- `Timestamp` - for date/time values |
| 136 | +- `StringValue` - for optional strings |
| 137 | +- `Int32Value`, `Int64Value` - for optional integers |
| 138 | +- And many more... |
| 139 | + |
| 140 | +## Key Features Demonstrated |
| 141 | + |
| 142 | +### 1. Type Safety |
| 143 | +```gleam |
| 144 | +// Compile-time type checking |
| 145 | +let user = proto.User( |
| 146 | + id: 42, |
| 147 | + name: "Alice", |
| 148 | + // ... other fields |
| 149 | +) |
| 150 | +``` |
| 151 | + |
| 152 | +### 2. Oneof Fields (Union Types) |
| 153 | +```gleam |
| 154 | +// Pattern matching on union types |
| 155 | +case message.data { |
| 156 | + option.Some(proto.TextData(text)) -> // Handle text |
| 157 | + option.Some(proto.NumericData(num)) -> // Handle number |
| 158 | + option.Some(proto.BinaryData(bytes)) -> // Handle binary |
| 159 | + option.None -> // Handle no data |
| 160 | +} |
| 161 | +``` |
| 162 | + |
| 163 | +### 3. Error Handling |
| 164 | +```gleam |
| 165 | +// Safe decoding with proper error handling |
| 166 | +case proto.decode_user(encoded_data) { |
| 167 | + Ok(user) -> // Successfully decoded |
| 168 | + Error(decode_errors) -> // Handle decode errors |
| 169 | +} |
| 170 | +``` |
| 171 | + |
| 172 | +### 4. Well-Known Types |
| 173 | +```gleam |
| 174 | +// Using Google's well-known types |
| 175 | +let timestamp = proto.Timestamp( |
| 176 | + seconds: 1640995200, |
| 177 | + nanos: 123456789, |
| 178 | +) |
| 179 | +``` |
| 180 | + |
| 181 | +## What's Working |
| 182 | + |
| 183 | +✅ **Basic Types**: All primitive types work correctly |
| 184 | +✅ **Enums**: User roles and other enums |
| 185 | +✅ **Oneof Fields**: Union types with proper type safety |
| 186 | +✅ **Well-Known Types**: Timestamp and other Google types |
| 187 | +✅ **Encoding/Decoding**: Round-trip serialization |
| 188 | +✅ **Type Safety**: Full Gleam compiler integration |
| 189 | + |
| 190 | +## Performance Notes |
| 191 | + |
| 192 | +- **Efficient Encoding**: Uses Protocol Buffer's compact binary format |
| 193 | +- **Memory Safe**: Leverages Gleam's memory safety guarantees |
| 194 | +- **Type Safe**: No runtime type errors with proper Gleam types |
| 195 | + |
| 196 | +## Integration |
| 197 | + |
| 198 | +To use Protozoa in your own project: |
| 199 | + |
| 200 | +1. **Add Dependency**: Add protozoa to your `gleam.toml` |
| 201 | +2. **Define Schemas**: Create `.proto` files |
| 202 | +3. **Generate Code**: Run `gleam run -m protozoa your.proto src/generated/` |
| 203 | +4. **Import & Use**: Import generated modules and use the types |
| 204 | + |
| 205 | +This example demonstrates that Protozoa successfully provides a complete, type-safe Protocol Buffer implementation for Gleam with excellent integration into the Gleam ecosystem. |
0 commit comments