I'm trying to implement a generic struct where it's clear from the beginnging that it's element 'provider' must be of a type that supports &myvar.provider[..] later on. But I'm unable to figure the correct Bound for this.
pub struct MyStruct<T: ??> { // T must support &x.provider[..]
pub provider: T,
}
Thanks a lot for your help
UPDATE: extended example. What I'm trying to achieve: data blocks can be up to 10GB. They can be provided as static b"aa" mostly for testing, read the file content into memory, or mmap the file content. No matter the provider, when processing the data we only use &[u8].
//
// A minimal example for my problem
//
use std::str;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::boxed::Box;
use memmap::{MmapOptions, Mmap};
#[derive(Debug)]
pub struct DBFileBuilder<T> { // what is the correct bound? T must support &x[..]
pub filename: String,
pub provider: Option<T>,
pub startpos: usize,
// ... several more
}
pub struct DBFile<'a, T> { // what is the correct bound? T must support &x[..]
pub filename: String,
pub provider: T,
pub data: &'a [u8],
// ... several more
}
impl<T> DBFileBuilder<T> {
fn default() -> Self {
Self {
filename: String::default(),
provider: None,
startpos: 0,
}
}
pub fn from_bytes(data: &[u8]) -> DBFileBuilder<&[u8]> {
DBFileBuilder {
provider: Some(&data),
..DBFileBuilder::default()
}
}
pub fn read_file(filename: &str) -> Result<DBFileBuilder<Box<[u8]>>, Box<dyn Error>> {
let mut file = File::open(&filename)?;
let fsize = file.metadata()?.len();
let mut provider = vec![0_u8; fsize as usize].into_boxed_slice();
let n = file.read(&mut provider)?;
Ok(DBFileBuilder {
filename: filename.to_string(),
provider: Some(provider),
..DBFileBuilder::default()
})
}
pub fn mmap_file(filename: &str) -> Result<DBFileBuilder<Mmap>, Box<dyn Error>> {
let file = File::open(&filename)?;
let provider = unsafe { MmapOptions::new().map(&file)? };
Ok(DBFileBuilder {
filename: filename.to_string(),
provider: Some(provider),
..DBFileBuilder::default()
})
}
pub fn init(&mut self) {
}
pub fn build<'a>(self) -> DBFile<'a, T> {
let provider = self.provider.expect("Provider not initialized");
self.init();
let data = &provider[self.startpos ..];
DBFile {
filename: self.filename,
provider,
data,
}
}
}
impl<'a, T> DBFile<'a, T> {
pub fn run(&self) {
return self.process(self.data)
}
pub fn process(&self, data: &[u8]) {
println!("data: {:?}", &data);
}
}
question from:
https://stackoverflow.com/questions/65853124/rust-generic-must-be-implement-xx 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…