Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jswrenn committed Oct 5, 2016
0 parents commit 88b2635
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "turnout-for-what"
version = "0.1.0"
authors = ["John Wrenn <[email protected]>"]

[[bin]]
name = "tfw"
46 changes: 46 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
================
turnout-for-what
================
.. image:: https://upload.wikimedia.org/wikipedia/commons/a/a2/V%C3%BDm%C4%9Bna_hrotit%C3%A1.jpg

Usage
-----
::

tfw SWITCH FILES...

``SWITCH``
A file descriptor yielding a stream of line-separated numbers. For every byte received from stdin, the last number received from SWITCH indicates the index of the FILE that the byte should be redirected to.

``FILES``
One or more file paths.

Example
-------
A load-balancer for the natural numbers::

#!/usr/bin/env bash
i=0;
echo "$i" > nat
trap "rm nat *.txt" EXIT

while true; do
wc -l *.txt
sleep 0.2
clear
done &

while true; do
sleep 0.2;
i=$(expr $i + 1);
echo "$i";
done \
| tee -a nat \
| cargo run -- \
<(while true; do
echo $(expr "$(tail -n 1 nat)" % 5)
done) \
0.txt 1.txt 2.txt 3.txt 4.txt

This script will create five text files, balance the natural numbers
between them, and continuously print their line counts.
58 changes: 58 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use std::io;
use std::env;
use std::thread;
use std::fs::File;
use std::io::Write;
use std::sync::Arc;
use std::io::BufRead;
use std::io::BufReader;
use std::fs::OpenOptions;
use std::sync::atomic::Ordering;
use std::sync::atomic::AtomicUsize;

fn main() {

let files = env::args().
skip(2).
map(|path|
OpenOptions::new().
read(false).
write(true).
create(true).
open(path)).
map(Result::unwrap).
collect::<Vec<File>>();

let target = Arc::new(AtomicUsize::new(0));
let target_writer = target.clone();

thread::spawn(move || {
for line in BufReader::new(
env::args().nth(1).
map(|path|
OpenOptions::new().
read(true).
write(false).
create(false).
open(path)).
unwrap().unwrap()).
lines() {
target_writer.store(
line.unwrap().parse::<usize>().unwrap_or(
target_writer.load(Ordering::Relaxed)),
Ordering::Relaxed);
}
});

let stdin = io::stdin();
let mut buffer = stdin.lock();

loop {
let consumed = buffer.fill_buf().
map(|bytes|
files.get(target.load(Ordering::Relaxed)).
map(|mut file| file.write(bytes))).
unwrap().unwrap().unwrap();
buffer.consume(consumed);
}
}

0 comments on commit 88b2635

Please sign in to comment.