تمرين إعادة البناء
Markdown Link Extractor
أعد كتابة مستخرج روابط Markdown يعرض النص والوجهة لكل رابط.
rust
~18 دقيقة
متوسط
أعد بناء الكود
Rebuild
هذا هو الكود. اكتبه بنفسك.
الكود المرجعي
use std::env;
use std::fs;
use std::io::{self, Read};
fn main() -> io::Result<()> {
let markdown = match env::args().nth(1) {
Some(path) => fs::read_to_string(path)?,
None => {
let mut input = String::new();
io::stdin().read_to_string(&mut input)?;
input
}
};
for link in extract_links(&markdown) {
println!("{} -> {}", link.text, link.url);
}
Ok(())
}
#[derive(Debug)]
struct Link {
text: String,
url: String,
}
fn extract_links(markdown: &str) -> Vec<Link> {
let bytes = markdown.as_bytes();
let mut links = Vec::new();
let mut index = 0;
while index + 3 < bytes.len() {
if bytes[index] == b'[' {
if let Some(close_text) = find_byte(bytes, index + 1, b']') {
if bytes.get(close_text + 1) == Some(&b'(') {
if let Some(close_url) = find_byte(bytes, close_text + 2, b')') {
links.push(Link {
text: markdown[index + 1..close_text].to_string(),
url: markdown[close_text + 2..close_url].to_string(),
});
index = close_url + 1;
continue;
}
}
}
}
index += 1;
}
links
}
fn find_byte(bytes: &[u8], start: usize, needle: u8) -> Option<usize> {
bytes
.iter()
.enumerate()
.skip(start)
.find_map(|(index, byte)| (*byte == needle).then_some(index))
}اكتب هنا