zefchain / serde-reflection

Rust libraries and tools to help with interoperability and testing of serialization formats based on Serde.
Apache License 2.0
137 stars 26 forks source link

[Bug] Swift types prefixed by module name #22

Open charypar opened 2 years ago

charypar commented 2 years ago

🐛 Bug

Generated swift code, which includes types that reference each other, prefixes local references with module name provided to CodeGeneratorConfig. The code fails to compile with an error "Cannot find type '' in scope".

The problem can be worked around by searching and replacing the module name followed by "." (e.g. "module.") with an empty string, effectively stripping the namespacing out of the generated code.

To reproduce

Types to be traced

#[derive(Serialize, Deserialize)]
pub struct Request {
    pub uuid: Vec<u8>,
    pub body: RequestBody,
}

#[derive(Serialize, Deserialize)]
pub enum RequestBody {
   // ... variants
}

Tracing and generating build.rs script

use rmm::{Request, RequestBody};
use serde_reflection::{Tracer, TracerConfig};
use std::{fs::File, io::Write, path::PathBuf};

fn main() {
    let mut tracer = Tracer::new(TracerConfig::default());
    tracer.trace_simple_type::<Request>().unwrap();
    tracer.trace_simple_type::<RequestBody>().unwrap();
    let registry = tracer.registry().unwrap();

    // Create Swift definitions.
    let mut source = Vec::new();
    let config = serde_generate::CodeGeneratorConfig::new("shared".to_string())
        .with_encodings(vec![serde_generate::Encoding::Bincode]);

    let generator = serde_generate::swift::CodeGenerator::new(&config);
    generator.output(&mut source, &registry).unwrap();

    let path = "./generated/shared_types.swift";
    let mut output = File::create(path).unwrap();
    write!(output, "{}", out).unwrap();
}

Relevant part of the generated Swift code

public struct Response: Hashable {
    @Indirect public var uuid: [UInt8]
    @Indirect public var body: shared.ResponseBody // "Error: Cannot find type 'shared' in scope"

    (...)

Removing shared. from the above resolves the problem.

Expected Behavior

Generated Swift code should compile without errors.

System information

Serde reflection v0.3.6 Serde generate v0.24.0

ma2bd commented 1 year ago

@charypar Thanks for the report. IIRC prefixing identifiers with the module name is useful. Have you tried a setup more similar to the test file swift_generation.rs ? (E.g. in this test, the module "Testing" matches the file name "Testing.swift". Your module is "shared" and the file is "shared_types.swift". Perhaps this helps?)