Skip to content

Instantly share code, notes, and snippets.

Created January 22, 2017 19:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/ed29892bd2f9de8f8ac109a7bec1c178 to your computer and use it in GitHub Desktop.
Save anonymous/ed29892bd2f9de8f8ac109a7bec1c178 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
use std::borrow::Borrow;
use std::rc::Rc;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// Status of a job
pub enum Status {
/// Indicates the job is not running and is not complete.
Pending,
/// Indicates the job is in progress.
Running,
/// Indicates the job has been completed.
Complete,
}
#[derive(Clone, Debug, PartialEq, Eq)]
/// Describes the state of a job.
pub struct State {
/// Name of the job
pub name: String,
/// Status of the job.
pub status: Status,
/// Total number of units of work in this job.
pub units_total: u32,
/// Number of units of work that have been completed.
pub units_complete: u32,
/// String describing the current state of the job.
pub description: String,
}
// Job SPI
pub trait Job {
fn do_work(&mut self);
fn borrow_state(&self) -> &State;
}
// View. For this snippet we just debug print.
pub trait View {
fn show(&self, job_states: &Vec<&State>);
}
struct StdOutView;
impl View for StdOutView {
fn show(&self, job_states: &Vec<&State>) {
println!("{:?}", job_states);
}
}
pub struct Activity<'a> {
jobs: Vec<Box<Job + 'a>>,
views: Vec<Rc<View>>,
}
impl<'a> Activity<'a> {
pub fn call(&mut self) {
// Initial display
{
let job_states = self.jobs.iter().map(|job| job.borrow_state()).collect();
for view in self.views.iter_mut() {
(Rc::borrow(view) as &View).show(&job_states);
}
}
// start the jobs
for job in self.jobs.iter_mut() {
job.do_work();
}
// TODO: poll for completion, update views while there are some incomplete jobs
// return some success code
}
}
// Code taken from https://tokio.rs/docs/getting-started/futures/
// const BIG_PRIME: u64 = 15485867;
// checks whether a number is prime, slowly
fn is_prime(num: u64) -> bool {
for i in 2..num {
if num % i == 0 {
return false;
}
}
true
}
// Some arbitrary job
// Finds all primes in the numbers passed to it, and populates the `primes` vector
pub struct PrimeJob<'p> {
state: State,
nums: Vec<u64>,
primes: &'p mut Vec<u64>,
}
impl<'p> PrimeJob<'p> {
pub fn new(nums: Vec<u64>, primes: &'p mut Vec<u64>) -> Self {
let state = State {
name: "PrimeJob".to_string(),
status: Status::Pending,
units_total: nums.len() as u32,
units_complete: 0,
description: "PrimeJob: Pending".to_string(),
};
PrimeJob {
state: state,
nums: nums,
primes: primes,
}
}
}
impl<'p> Job for PrimeJob<'p> {
// TODO: should do_work be non mutable?
fn do_work(&mut self) {
let mut index = 0;
for i in self.nums.iter() {
self.state = State {
name: "PrimeJob".to_string(),
status: Status::Running,
units_total: self.nums.len() as u32,
units_complete: index as u32,
description: format!("Checking if {} is prime", i),
};
if is_prime(*i) {
self.primes.push(*i);
}
index += 1;
}
self.state = State {
name: "PrimeJob".to_string(),
status: Status::Complete,
units_total: self.nums.len() as u32,
units_complete: index as u32,
description: "Complete!".to_string(),
};
}
fn borrow_state(&self) -> &State {
&self.state
}
}
fn main() {
let candidates = vec![3, 4, 5, 6];
let mut primes = vec![];
{
let mut activity = Activity {
jobs: vec![Box::new(PrimeJob::new(candidates, &mut primes))],
views: vec![Rc::new(StdOutView)],
};
activity.call();
}
println!("Primes: {:?}", primes);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment