CodeBlanks Logo Icon CodeBlanks

Searching with traits

Add search with a Searchable trait.

Searching with a trait

For the shelf to search, its items must be able to say whether they match a query. We express this with a trait and offer the search method only for items implementing it:

pub trait Aranabilir {
    fn eslesir(&self, sorgu: &str) -> bool;
}

impl<T: Aranabilir> Raf<T> {
    pub fn ara(&self, sorgu: &str) -> Vec<&T> {
        self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
    }
}

Raf<u32> is still valid but has no ara method, because u32 isn't Aranabilir.

Implementation for Kitap

Let a book match if the query appears in its title or author. Both sides are lowercased to ignore case differences:

impl Aranabilir for Kitap {
    fn eslesir(&self, sorgu: &str) -> bool {
        let s = sorgu.to_lowercase();
        self.ad.to_lowercase().contains(&s)
            || self.yazar.to_lowercase().contains(&s)
    }
}

Since the trait is in the same module, it can access Kitap's private fields.

Practice Search the shelf

With the previous Kitap and Raf, write the Aranabilir trait and the ara method. Add Tutunamayanlar (Oğuz Atay, 1972), Tehlikeli Oyunlar (Oğuz Atay, 1973) and Kürk Mantolu Madonna (Sabahattin Ali, 1943) to the shelf. Print the result of ara("atay") as 2: Tutunamayanlar, Tehlikeli Oyunlar.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
mod kitaplik {
    pub struct Kitap {
        ad: String,
        yazar: String,
        yil: u16,
    }

    impl Kitap {
        pub fn new(ad: &str, yazar: &str, yil: u16) -> Self {
            Self {
                ad: ad.to_string(),
                yazar: yazar.to_string(),
                yil,
            }
        }
        pub fn ad(&self) -> &str {
            &self.ad
        }
        pub fn yil(&self) -> u16 {
            self.yil
        }
    }

    pub struct Raf<T> {
        ogeler: Vec<T>,
    }

    impl<T> Raf<T> {
        pub fn new() -> Self {
            Self { ogeler: Vec::new() }
        }
        pub fn ekle(&mut self, x: T) {
            self.ogeler.push(x);
        }
        pub fn len(&self) -> usize {
            self.ogeler.len()
        }
    }

    pub trait Aranabilir {
        fn eslesir(&self, sorgu: &str) -> bool;
    }

    impl Aranabilir for Kitap {
        fn eslesir(&self, sorgu: &str) -> bool {
            let s = sorgu.to_lowercase();
            self.ad.to_lowercase().contains(&s) || self.yazar.to_lowercase().contains(&s)
        }
    }

    impl<T: Aranabilir> Raf<T> {
        pub fn ara(&self, sorgu: &str) -> Vec<&T> {
            self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
        }
    }
}

use kitaplik::{Kitap, Raf};

fn main() {
    let mut raf = Raf::new();
    raf.ekle(Kitap::new("Tutunamayanlar", "Oğuz Atay", 1972));
    raf.ekle(Kitap::new("Tehlikeli Oyunlar", "Oğuz Atay", 1973));
    raf.ekle(Kitap::new("Kürk Mantolu Madonna", "Sabahattin Ali", 1943));
    let bulunan = raf.ara("atay");
    let adlar: Vec<&str> = bulunan.iter().map(|k| k.ad()).collect();
    println!("{}: {}", bulunan.len(), adlar.join(", "));
}

Expected output

2: Tutunamayanlar, Tehlikeli Oyunlar

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why does <code>ara</code> return <code>Vec&lt;&amp;T&gt;</code> rather than <code>Vec&lt;T&gt;</code>?

  • To show the items without moving them off the shelf or copying them Correct answer
  • &T prints faster
  • Vec<T> can't be generic
  • No difference

Explanation: Items can't be moved out of a shelf borrowed with &self; returning references is also cheaper than copying.

2 Bounded search

Question
impl<T: ____> Raf<T> {
    pub fn ara(&self, sorgu: &str) -> Vec<&T> {
        self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
    }
}
Answer
impl<T: Aranabilir> Raf<T> {
    pub fn ara(&self, sorgu: &str) -> Vec<&T> {
        self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
    }
}

Explanation: ara exists only on shelves holding Aranabilir items.

3 Query and matching books

Term Meaning
"atay" Tutunamayanlar, Tehlikeli Oyunlar
"MADONNA" Kürk Mantolu Madonna
"sabahattin" Only Ali's book
"xyz" Empty vector

All lessons in Intermediate