[Beginner] Function without enumerate

Hello, can anyone help me write this function without using enumerate / join?

fn draw(list: &[(String, bool)], height: usize, y: usize, offset: usize) {
    eprint!("\x1b[2J\x1b[H");
    for (i, (name, is_dir)) in list.iter().skip(offset).take(height).enumerate() {
        let newline = if i > 0 { "\n" } else { "" };
        let slash = if *is_dir { "/" } else { "" };
        eprint!("{newline}{slash}{name}");
    }
    eprint!("\x1b[{};1H", y - offset + 1);
}

That's the closest I got:

fn draw(list: &[(String, bool)], height: usize, y: usize, offset: usize) {
    eprint!("\x1b[2J\x1b[H");
    let mut first = true;
    for (name, is_dir) in list.iter().skip(offset).take(height) {
        let newline = if first { "" } else { "\n" };
        let slash = if *is_dir { "/" } else { "" };
        eprint!("{newline}{slash}{name}");
        first = false;
    }
    eprint!("\x1b[{};1H", y - offset + 1);
}

But using this first variable seems wrong.
Full code available here

You could advance the iterator first by one position by calling next, and then consume the rest of the iterator.

Yes, but in this version, I don't like that slash is repeated twice.

    ...
        let slash = if *is_dir { "/" } else { "" };
        ...
            let slash = if *is_dir { "/" } else { "" };

Use map to remove some redundancy.

    let mut iter =
        list.iter()
            .skip(offset)
            .take(height)
            .map(|(n, d)| if *d { (n, "/") } else { (n, "") });

    eprint!("\x1b[2J\x1b[H");
    if let Some((name, slash)) = iter.next() {
        eprint!("{slash}{name}");
    }
    for (name, slash) in iter {
        eprint!("\n{slash}{name}");
    }
    eprint!("\x1b[{};1H", y - offset + 1);

use itertools::Itertools;

fn draw(list: &[(String, bool)], height: usize, y: usize, offset: usize) {
    eprint!("\x1b[2J\x1b[H");
    for name in list
        .iter()
        .skip(offset)
        .take(height)
        .map(|(name, is_dir)| format!("{}{name}", if *is_dir { "/" } else { "" }))
        .intersperse("\n".into())
    {
        eprint!("{name}");
    }
    eprint!("\x1b[{};1H", y - offset + 1);
}

This is possibly wrong but I struggled to follow the intend so I created a few types (playground):

struct File {
    name: String,
    is_dir: bool,
}

impl File {
    fn new(name: &str, is_dir: bool) -> Self {
        File {
            name: String::from(name),
            is_dir,
        }
    }
}
struct Window {
    skip: usize,
    take: usize,
}

/// Something with a window of files
fn draw(list: &[File], window: Window, y: usize) {
    eprint!("\x1b[2J\x1b[H");

    let mut file_iter = list.iter().skip(window.skip).take(window.take);
    let File { name, is_dir } = file_iter.next().unwrap();

    let slash = if *is_dir { "/" } else { "" };
    eprint!("{slash}{}", name);

    for File { name, is_dir } in file_iter {
        let slash = if *is_dir { "/" } else { "" };
        eprint!("\n{slash}{}", name);
    }
    eprint!("\x1b[{};1H", y - window.skip + 1);
}

fn main() {
    let list = [
        File::new("hello", true),
        File::new("hello", false),
        File::new("hellw", true),
    ];
    let window = Window { skip: 1, take: 1 };
    draw(&list, window, 1);
}

Thanks for the answers, in the end I came to this version:

fn list(path: &Path) -> Vec<(String, bool)> {
    let mut entries = Vec::new();
    for entry in read_dir(path).into_iter().flatten().flatten() {
        let is_dir = entry.file_type().is_ok_and(|file_type| file_type.is_dir());
        let mut name = entry.file_name().to_string_lossy().into_owned();
        if is_dir {
            name.insert(0, '/');
        }
        entries.push((name, is_dir));
    }
    entries.sort_unstable_by(|a, b| (!a.1, &a.0).cmp(&(!b.1, &b.0)));
    entries.iter_mut().skip(1).for_each(|(name, _)| name.insert(0, '\n'));
    entries
}

fn draw(list: &[(String, bool)], height: usize, y: usize, offset: usize) {
    eprint!("\x1b[2J\x1b[H");
    for (name, _) in list.iter().skip(offset).take(height) {
        eprint!("{name}");
    }
    eprint!("\x1b[{};1H", y - offset + 1);
}