2014-12-14 4 views
1

Трубчатый фильтр - это программа для падения между Unix-трубами: source | filter | sink. Я бы хотел, чтобы он делал как можно меньше буферизации и обрабатывал вещи по мере их поступления, а не читал все и только начинал обрабатывать данные на EOF.Как написать фильтр трубы в Rust?

Я очень новичок в Rust, и это учебный проект. Вся вещь фильтра для труб предназначена для того, чтобы я мог играть с строковой обработкой в ​​командной строке и возникает из-за необходимости получать несаминированный JSON от conky и очищать его для i3bar.

Вот что у меня есть. Он не выполняет никакой обработки и должен просто сбрасывать stdin в stdout.

Я не уверен, будет ли read_line() блокироваться до тех пор, пока не будет найден символ новой строки, и как проверить, вернул ли он что-то, с чем я могу работать. Я знаю, что он возвращает IoResult, но я не смог узнать, как сделать матч против него. Кажется, в этом контексте используется макрос try!, но я не уверен, как это сделать.

Когда он достигает звонка sleep(), он, кажется, спит бесконечно.

use std::io; 
use std::io::timer; 
use std::time::Duration; 

fn main() { 
    let mut reader = io::stdin(); 
    let interval = Duration::milliseconds(1000); 
    let mut line; 

    loop { 
     line = reader.read_line(); 
     print!("{}", line); 

     timer::sleep(interval); 
    } 
} 
+2

Вам, в конечном счете, придется выбирать, что вы подразумеваете под «эффективным». Если вы делаете «как можно меньше буферизации», тогда вы будете использовать меньше памяти, но, возможно, больше времени процессора или пользователя. Обычно вы можете быть эффективными в одной области, а не в другой. – Shepmaster

+0

Ваш код кажется достаточно эхо-вывода для вывода (кроме 'line' является результатом, поэтому вывод завернут в' Ok' или 'Err') – Shepmaster

+0

Плохая формулировка с моей стороны. С «эффективным» я имел в виду «не буферизует навсегда», а не ресурсоэффективно. – mkaito

ответ

1

Вы забита 3 (или более) отдельные вопросы здесь ...

Я уверен в том, read_line() блокирует до символа новой строки не найден.

The docs for read_line не являются специфичными по этому вопросу, но я думаю, что не вернется, пока он не был в состоянии прочитать полную строку (или имеет ошибку).

Как проверить, вернул ли он что-то, с чем я могу работать. Я знаю, что он возвращает IoResult, но мне не удалось выяснить, как сделать матч против него.

IOResult в основном другое название Result, что является нормальным enum. Вы можете соответствовать его следующим образом:

match io_method() { 
    Ok(_) => thing_1(), 
    Err(_) => thing_2(), 
} 

Обычно вы могли бы сделать что-то полезное со значениями в Ok и Err.

Кажется, попробуйте! макрос используется в этом контексте, но я не уверен, как это сделать.

docs for try! показать, как оно реализовано. Это простой способ сказать «если произошла ошибка, верните эту ошибку моему абоненту». В какой-то момент вам нужно решить, что делать с ошибкой, но try! говорит об этом позже.

+0

Если я правильно понимаю вещи, на stdin есть неявный буфер, и я могу просто читать из него строку за раз, не дожидаясь, когда она получит EOL, правильно? Нужно ли мне что-либо делать, чтобы предотвратить буферизацию stdout при печати? – mkaito

+0

Это звучит как отдельный вопрос. – Shepmaster

+0

Роджер, что. Вывод нового вопроса. – mkaito

Смежные вопросы