Support no_std in roto-runtime

Add #![no_std] to the runtime crate and introduce optional std and
alloc features. Update the code generator to be compatible and add a
no_std_test example. Remove the generator binary.
This commit is contained in:
2026-05-17 19:55:44 -07:00
parent 956993d1d0
commit fa4d8cca83
8 changed files with 62 additions and 50 deletions
-42
View File
@@ -1,42 +0,0 @@
use clap::Parser;
use roto_codegen::generator::generate_rust_code;
use roto_codegen::google::protobuf::descriptor::FileDescriptorSet;
use std::fs;
use std::path::PathBuf;
#[derive(Parser)]
#[command(
author,
version,
about = "Generates Rust accessor and builder code from a protobuf descriptor set"
)]
struct Args {
/// Path to the descriptor set file (.desc)
#[arg(short, long)]
input: PathBuf,
/// Path to the output directory
#[arg(short, long)]
output: PathBuf,
/// Files to generate. If omitted, all files are generated.
#[arg(short, long, value_delimiter = ',')]
files: Option<Vec<String>>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
let data = fs::read(&args.input)?;
let set = FileDescriptorSet::new(&data).expect("Failed to parse FileDescriptorSet");
let files = generate_rust_code(&set, args.files.as_deref(), true);
for (filename, content) in files {
let path = args.output.join(filename);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
fs::write(path, content)?;
}
Ok(())
}
+4 -4
View File
@@ -6,7 +6,7 @@ use roto_runtime::ProtoAccessor;
use std::collections::{HashMap, HashSet};
use std::str;
const DATA_IMPORTS: &str = "use roto_runtime::{ProtoAccessor, ProtoBuilder, Result, RotoError, read_varint, RepeatedFieldIterator, RotoMessage};\nuse std::str;\nuse bytes::{Bytes, BytesMut, Buf, BufMut};\n";
const DATA_IMPORTS: &str = "use roto_runtime::{ProtoAccessor, ProtoBuilder, Result, RotoError, read_varint, RepeatedFieldIterator, RotoMessage};\nuse core::str;\nuse bytes::{Bytes, BytesMut, Buf, BufMut};\n";
const SERVICE_IMPORTS: &str = "use tonic::{Request, Response, Status};\nuse tokio_stream::Stream;\nuse std::pin::Pin;\nuse std::sync::Arc;\nuse std::task::{Context, Poll};\nuse std::future::Future;\nuse tonic::body::BoxBody;\nuse tower::Service;\nuse futures_util::StreamExt;\nuse http_body_util::BodyExt;\nuse http_body::Body;\nuse crate::{BufferPool, StatusBody};\n";
pub fn to_pascal_case(s: &str) -> String {
@@ -440,18 +440,18 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
output.push_str(&format!(" pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> {{\n self.builder.finish()\n }}\n}}\n\n"));
output.push_str(&format!("pub struct Owned{} {{\n", msg_name));
output.push_str(&format!("#[cfg(feature = \"alloc\")]\npub struct Owned{} {{\n", msg_name));
output.push_str(" pub data: bytes::Bytes,\n");
output.push_str("}\n\n");
output.push_str(&format!("impl roto_runtime::RotoOwned for Owned{} {{\n", msg_name));
output.push_str(&format!("#[cfg(feature = \"alloc\")]\nimpl roto_runtime::RotoOwned for Owned{} {{\n", msg_name));
output.push_str(&format!(" type Reader<'a> = {}<'a>;\n", msg_name));
output.push_str(&format!(" fn reader(&self) -> {}<'_> {{\n", msg_name));
output.push_str(&format!(" {}::new(&self.data).expect(\"failed to create reader\")\n", msg_name));
output.push_str(" }\n");
output.push_str("}\n\n");
output.push_str(&format!("impl roto_runtime::RotoMessage for Owned{} {{\n", msg_name));
output.push_str(&format!("#[cfg(feature = \"alloc\")]\nimpl roto_runtime::RotoMessage for Owned{} {{\n", msg_name));
output.push_str(" fn decode(buf: bytes::Bytes) -> roto_runtime::Result<Self> {\n");
output.push_str(&format!(" Ok(Owned{} {{ data: buf }})\n", msg_name));
output.push_str(" }\n\n");