it-praxisportal/courses/rust/10_generics_und_dynamischer_dispatch/aufgabe.rs

114 lines
3.3 KiB
Rust

// ============================================================================
// 🦀 RUST 10: GENERICS & DYNAMISCHER DISPATCH (TRAIT OBJECTS)
// ============================================================================
// 🎯 TODO 1: Implementiere das generische Struct 'DataContainer<T>'
// Felder:
// - pub value: T
// - pub tag: String
//
// Methoden:
// - pub fn new(value: T, tag: &str) -> Self
// - pub fn get_value(&self) -> &T
// - pub fn transform<U, F: FnOnce(T) -> U>(self, op: F) -> DataContainer<U>
#[derive(Debug, Clone, PartialEq)]
pub struct DataContainer<T> {
pub value: T,
pub tag: String,
}
impl<T> DataContainer<T> {
// TODO: new und get_value implementieren
pub fn new(value: T, tag: &str) -> Self {
Self {
value,
tag: tag.to_string(),
}
}
pub fn get_value(&self) -> &T {
&self.value
}
pub fn transform<U, F: FnOnce(T) -> U>(self, op: F) -> DataContainer<U> {
// TODO: op(self.value) anwenden und neuen DataContainer mit unverändertem tag erzeugen
let new_val = op(self.value);
DataContainer {
value: new_val,
tag: self.tag,
}
}
}
// 🎯 TODO 2: Definiere den Trait 'DataPlugin'
// Methoden:
// - fn name(&self) -> &str;
// - fn process(&self, input: &str) -> String;
pub trait DataPlugin {
// TODO: Methodensignaturen deklarieren
}
// 🎯 TODO 3: Implementiere konkrete Plugins
// a) 'UppercasePlugin' -> name: "uppercase", process: input.to_uppercase()
pub struct UppercasePlugin;
// b) 'PrefixPlugin' -> Felder: pub prefix: String
// name: "prefix", process: format!("{}{}", self.prefix, input)
pub struct PrefixPlugin {
pub prefix: String,
}
// c) 'CensorPlugin' -> Felder: pub forbidden: String, pub replacement: String
// name: "censor", process: input.replace(&self.forbidden, &self.replacement)
pub struct CensorPlugin {
pub forbidden: String,
pub replacement: String,
}
// TODO: impl DataPlugin for UppercasePlugin ...
// TODO: impl DataPlugin for PrefixPlugin ...
// TODO: impl DataPlugin for CensorPlugin ...
// 🎯 TODO 4: Implementiere 'PluginPipeline' mit dynamischem Dispatch (dyn Trait)
// Feld:
// - plugins: Vec<Box<dyn DataPlugin>>
pub struct PluginPipeline {
pub plugins: Vec<Box<dyn DataPlugin>>,
}
impl PluginPipeline {
pub fn new() -> Self {
Self {
plugins: Vec::new(),
}
}
pub fn register(&mut self, plugin: Box<dyn DataPlugin>) {
// TODO: Plugin zur Liste hinzufügen
}
pub fn count(&self) -> usize {
self.plugins.len()
}
pub fn plugin_names(&self) -> Vec<&str> {
// TODO: Namen aller Plugins als Vec<&str> sammeln
Vec::new()
}
pub fn execute(&self, input: &str) -> String {
// TODO: String durch alle Plugins sequentiell leiten und Endergebnis zurückgeben
input.to_string()
}
}
fn main() {
println!("=== Rust 10: Generics & Dynamic Dispatch ===");
let container = DataContainer::new(100, "sensor-01");
let transformed = container.transform(|x| x * 2);
println!("Transformed: {:?} (Val: {})", transformed, transformed.get_value());
let mut pipeline = PluginPipeline::new();
// pipeline.register(Box::new(UppercasePlugin));
println!("Pipeline Plugins: {}", pipeline.count());
}