Factory Struct with multiple trait implementations doesnt work

Hi I have a factory method:

use zip::ZipWriter as OldZipWriter;
use zip::result::ZipResult as OldZipResult;
use zip::result::ZipError as OldZipError;
use zip::write::FileOptions as OldFileOptions;
use zip::CompressionMethod as OldCompressionMethod;

use zip_next::result::ZipError;
use zip_next::write::FileOptions;
use zip_next::ZipWriter;
use zip_next::CompressionMethod;

pub fn NewCompressor(Compressor_type:&str)->Result<impl Compressor,String>{
        let ResCT=CompressorType::from_str(Compressor_type,true);
        let CT:CompressorType;
        match ResCT{
                               Err(e)=>{return Err(format!("Unknown compression type {}",e))}
                               Ok(s)=>{CT=s}
        }
        match CT{
            CompressorType::Zip=>{
                            return Ok(ZipCompressor1 {
                                         compression_method:zip::CompressionMethod::Deflated,
                                         zip_file_handle:None::<OldZipWriter<File>>,
                                         file_options:None::<OldFileOptions>})
                                    },
            CompressorType::Zip2=>{
                           return Ok(ZipCompressor2{
                                  compression_method:zip_next::CompressionMethod::Deflated,
                                  zip_file_handle:None::<ZipWriter<File>>,
                                  file_options:None::<FileOptions>,})
            },
            _=>Err(format!("Compressor {} is not available",CT))
        }
    }

pub trait Compressor {
...
    }

pub struct ZipCompressor1 {
...
    }
impl ZipCompressor1 {
...
}
impl Compressor for ZipCompressor2 {
}
pub struct ZipCompressor2 {
...
    }
impl ZipCompressor2 {
...
}
impl Compressor for ZipCompressor2 {
...
}

I am receiving the following error from rust (1.70) compiler:

error[E0308]: mismatched types
   --> src\FileCompression.rs:49:27
    |
49  |                   return Ok(ZipCompressor2{
    |  ________________________--_^
    | |                        |
    | |                        arguments to this enum variant are incorrect
50  | |                     compression_method:zip_next::CompressionMethod::Deflated,
51  | |                     zip_file_handle:None::<ZipWriter<File>>,
52  | |                     file_options:None::<FileOptions>,
53  | |                 })
    | |_________________^ expected `ZipCompressor1`, found `ZipCompressor2`
    |
help: the type constructed contains `ZipCompressor2` due to the type of the argument passed
   --> src\FileCompression.rs:49:24
    |
49  |                    return Ok(ZipCompressor2{
    |  _________________________^__-
    | | ________________________|
    | ||
50  | ||                     compression_method:zip_next::CompressionMethod::Deflated,
51  | ||                     zip_file_handle:None::<ZipWriter<File>>,
52  | ||                     file_options:None::<FileOptions>,
53  | ||                 })
    | ||_________________-^
    | |__________________|
    |                    this argument influences the type of `Ok`
note: tuple variant defined here
   --> C:\Users\MuratCudiErentürk\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\result.rs:507:5
    |
507 |     Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
    |     ^^

Since both of structs implement trait Compressor, and method output is defined as Result<impl Compressor,String> I am assuming I should be able to return 2 different struct types, what am I missing?

Please format your code properly, it's hard to read your post like this.

no, impl Trait is still a single type, it's a compiler synthesized opaque type which you cannot name directly. if you want to return different types at runtime, you need trait objects, i.e. dyn Trait (as opposed to impl Trait), but dyn Trait is unsized, so you must use Box, Rc, Arc, etc.

one alternative to trait objects is to use an enum (a.k.a. sum type) as return type. the crate enum-dispatch might be interesting to check out:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.