texnouz-contracts

Crates.iotexnouz-contracts
lib.rstexnouz-contracts
version0.1.2
created_at2026-01-10 06:31:47.367878+00
updated_at2026-01-10 06:31:47.367878+00
descriptiongRPC contracts library with auto-generated Rust code from proto files
homepage
repositoryhttps://github.com/ali-0211-tr/contracts
max_upload_size
id2033598
size165,699
Alishan Usmanov (Ali-0211-TR)

documentation

README

Contracts

A Rust library for gRPC contracts with auto-generated code from Protocol Buffer definitions using tonic and prost.

Features

  • 🚀 Automatic Rust code generation from .proto files
  • 🔄 gRPC client and server code generation via tonic
  • 📦 Ready for publishing to crates.io
  • 🤖 GitHub Actions workflow for automated builds and testing
  • ✨ Built-in helper utilities for common operations
  • 🔐 Authentication helpers and timestamp utilities

Installation

Add this to your Cargo.toml:

[dependencies]
contracts = "0.1.0"

Or install from GitHub:

[dependencies]
contracts = { git = "https://github.com/yourusername/contracts" }

Usage

Adding Proto Files

  1. Add your .proto files to the proto/ directory
  2. The build script will automatically discover and compile them
  3. Run cargo build to generate Rust code

Example proto file structure:

proto/
├── user.proto
├── auth.proto
└── common.proto

Using Generated Code

use contracts::generated;
use contracts::tonic;

// Use generated types and services
// The generated modules will be available based on your proto package names

// Example: Using helpers
use contracts::utils::{current_timestamp, add_auth_token};

fn main() {
    let timestamp = current_timestamp();
    println!("Current timestamp: {:?}", timestamp);
}

Generated Module Structure

After building, generated code will be included in the generated module. To use specific proto packages:

// In your lib.rs, add:
pub mod generated {
    tonic::include_proto!("user");
    tonic::include_proto!("auth");
    tonic::include_proto!("common");
}

Creating a gRPC Client

use contracts::generated::user::user_service_client::UserServiceClient;
use contracts::generated::user::GetUserRequest;
use contracts::tonic::transport::Channel;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to the server
    let channel = Channel::from_static("http://[::1]:50051")
        .connect()
        .await?;
    
    let mut client = UserServiceClient::new(channel);
    
    // Make a request
    let request = tonic::Request::new(GetUserRequest {
        id: "123".to_string(),
    });
    
    let response = client.get_user(request).await?;
    println!("Response: {:?}", response.into_inner());
    
    Ok(())
}

Creating a gRPC Server

use contracts::generated::user::{
    user_service_server::{UserService, UserServiceServer},
    GetUserRequest, GetUserResponse, User,
};
use contracts::tonic::{transport::Server, Request, Response, Status};

#[derive(Debug, Default)]
pub struct MyUserService {}

#[tonic::async_trait]
impl UserService for MyUserService {
    async fn get_user(
        &self,
        request: Request<GetUserRequest>,
    ) -> Result<Response<GetUserResponse>, Status> {
        let req = request.into_inner();
        
        // Your business logic here
        let user = User {
            id: req.id,
            username: "john_doe".to_string(),
            email: "john@example.com".to_string(),
            full_name: "John Doe".to_string(),
            created_at: Some(contracts::current_timestamp()),
            updated_at: Some(contracts::current_timestamp()),
            is_active: true,
            role: "user".to_string(),
        };
        
        Ok(Response::new(GetUserResponse { user: Some(user) }))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let addr = "[::1]:50051".parse()?;
    let service = MyUserService::default();
    
    Server::builder()
        .add_service(UserServiceServer::new(service))
        .serve(addr)
        .await?;
    
    Ok(())
}

Development

Prerequisites

  • Rust 1.70+
  • Protocol Buffer Compiler (protoc)

Install protoc:

Ubuntu/Debian:

sudo apt-get install protobuf-compiler

macOS:

brew install protobuf

Windows: Download from GitHub releases

Building

cargo build

This will:

  1. Find all .proto files in the proto/ directory
  2. Generate Rust code using tonic and prost
  3. Compile the library

Testing

cargo test

Formatting and Linting

cargo fmt
cargo clippy

Project Structure

contracts/
├── .github/
│   └── workflows/
│       ├── generate-proto.yml  # Auto-generate code on proto changes
│       └── publish.yml         # Publish to crates.io
├── proto/                      # Proto definition files
│   ├── user.proto
│   ├── auth.proto
│   └── common.proto
├── src/
│   └── lib.rs                  # Main library file
├── build.rs                    # Build script for code generation
├── Cargo.toml
└── README.md

GitHub Actions

This project includes two GitHub Actions workflows:

1. Generate Proto Code (generate-proto.yml)

Automatically runs on:

  • Push to main or develop branches
  • Pull requests to main or develop
  • Changes to proto files, build.rs, or Cargo.toml

Actions:

  • Builds the project (generating proto code)
  • Runs tests
  • Checks code formatting
  • Runs clippy lints
  • Verifies generated code is up to date

2. Publish to Cargo (publish.yml)

Runs on:

  • GitHub releases
  • Manual workflow dispatch

Actions:

  • Builds in release mode
  • Runs tests
  • Publishes to crates.io (requires CARGO_REGISTRY_TOKEN secret)

Publishing

To crates.io

  1. Update version in Cargo.toml
  2. Update README.md and CHANGELOG.md
  3. Create a git tag:
    git tag v0.1.0
    git push origin v0.1.0
    
  4. Create a GitHub release
  5. The publish workflow will automatically publish to crates.io

Or manually:

cargo publish

To GitHub Packages

The library can also be used directly from GitHub:

[dependencies]
contracts = { git = "https://github.com/yourusername/contracts", tag = "v0.1.0" }

Configuration

Cargo.toml Features

  • default: Standard features
  • serde: Enable serde serialization for generated types

Enable serde support:

[dependencies]
contracts = { version = "0.1.0", features = ["serde"] }

Build Script Configuration

The build.rs script can be customized:

tonic_build::configure()
    .build_server(true)   // Generate server code
    .build_client(true)   // Generate client code
    .type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
    .compile(&proto_files, &["proto"])?;

Helper Utilities

The library includes helpful utilities:

use contracts::utils::*;

// Add authentication token to requests
let request = add_auth_token(request, "your-token");

// Get current timestamp
let timestamp = current_timestamp();

// Validate required fields
let value = require_field(optional_value, "field_name")?;

Examples

See the examples directory for complete working examples:

  • client.rs - gRPC client example
  • server.rs - gRPC server example

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add your proto files or improvements
  4. Run tests and linting
  5. Submit a pull request

License

This project is licensed under MIT OR Apache-2.0.

Resources

Commit count: 0

cargo fmt