Recent Entries 10
- pattern minor 112d agoDesigning posts: state machineIn the Object-Oriented Design Pattern Implementation chapter of the second edition of The Rust Programming Language, the basic code structure is given and it suggests trying to add features: This implementation is easy to extend to add more functionality. Here are some changes you can try making to the code in this section to see for yourself what it's like to maintain code using this pattern over time: - Only allow adding text content when a post is in the `Draft` state - Add a `reject` method that changes the post's state from `PendingReview` back to `Draft` - Require two calls to `approve` before changing the state to `Published` Please critique my approach: ``` struct Post { content: String } struct DraftPost { content: String } struct PendingPost { content: String, approvals: u32 } impl Post { fn new() -> DraftPost { DraftPost { content: String::new() } } fn content(&self) -> &str { &self.content } } impl DraftPost { fn req_review(self) -> PendingPost { PendingPost { content: self.content, approvals: 0 } } fn add_text(&mut self, content: &str) { self.content.push_str(content); } } enum PublishResult { PendingPost(PendingPost), Post(Post) } impl PendingPost { fn approve(&mut self) { self.approvals += 1; } fn reject(self) -> DraftPost { DraftPost { content: self.content } } fn publish(self) -> PublishResult { if self.approvals > 1 { PublishResult::Post(Post{content: self.content}) } else { PublishResult::PendingPost(self) } } } #[cfg(test)] mod tests { use super::*; #[test] fn publish_workflow() { let mut draft = Post::new(); draft.add_text("ashish first post"); let mut pending = draft.req_review(); pending.approve(); pending.approve(); let publish = pending.p
- pattern minor 112d agoRust: Prime numbersA first attempt to implement the Sieve of Eratosthenes to find all the prime numbers from 2 up to a given number resulted in this brute force algorithm. A user pointed out, that this is in fact not the Sieve of Eratosthenes, but just a brute force algorithm and should be reviewed as such. ``` #![feature(inclusive_range_syntax)] pub fn primes_up_to(limit: u64) -> Vec { let mut vec: Vec = (2...limit).collect::>(); for p in 2...limit { vec.retain(|&x| x <= p || x % p != 0); } vec } ```
- pattern minor 112d agoA DFS sudoku solverThis is my attempt at a Sudoku solver using a DFS approach. I mainly developed it to become a better Rust developer, but if you have any performance tips, I will be glad to hear them :) My program works for any `dim > 1`, but these take a long time to calculate. You may wish to limit running the code to 2 or 3 dimensions. Here are some inputs you can use to test it. If my program returns the original sudoku, then there are no solutions. `9 x x x 7 x 6 8 1 x x x x x 6 x 4 x x 3 x x x x x x 9 x 6 x x x 1 5 x 7 x x x x x x x x x 8 x 3 7 x x x 1 x 1 x x x x x x 3 x x 9 x 6 x x x x x 3 5 2 x 1 x x x 4 ` `x x x 9 x x 4 x x x x x x x 4 5 7 x 7 x x 3 x x x 1 2 1 x x x x x 2 4 x x 9 8 x x x 1 3 x x 3 4 x x x x x 5 5 2 x x x 6 x x 8 x 6 7 8 x x x x x x x 3 x x 1 x x x ` `x x 1 x 6 8 5 2 x x x x 2 x x x x 1 x x 2 5 1 9 x 3 x x x 8 x 2 4 7 x x 6 x 4 x x x 3 x 2 x x 7 3 8 x 9 x x x 9 x 1 3 5 2 x x 4 x x x x 6 x x x x 8 5 4 7 x 6 x x ` Here's my code: ``` #[macro_use] extern crate text_io; use std::io; // struct to represent a sudoku struct Sudoku { size: u32, board: Vec>, } fn generate_sudoku(size: u32) -> Sudoku { let dim = (size * size) as usize; let mut sudoku = Sudoku { size: size, board: Vec::new(), }; // fill the sudoku with the specified values for row in 0..dim { sudoku.board.push(Vec::new()); for _ in 0..dim { let num: String = read!(); let mut is_number = true; for ch in num.chars() { if !ch.is_digit(10) { is_number = false; break; } } let number = if is_number { let num = num.parse::().expect("Not a number! Aborting..."); if num > (dim as u32) { 0 } else { num } } else { 0 }; sudoku.board[row].push(number); } } sudoku } // helper function to determine whether
- pattern minor 112d agoLexer Implementation in Rust - `PhantomData` AwkwardnessI've been working on a Tokeniser/Lexer in Rust. I would like to have the tokeniser take input from different sources, such as files or in-memory strings. To abstract over this concern i've created a trait `Source`. This has left me with a wonky situation where I appear to need a `PhantomData` member in the token iterator. I've created a cut-down example here: ``` /// Source of Characters /// /// In this example all that a source can do is be sliced to retrieve /// a subsection of the overall character buffer. trait Source { /// Character at Offset /// /// Gets the character at the given offset in the buffer and /// returns it. If no character is available at that offset `None` /// is returned. fn at(&self, offset: usize) -> Option; /// Slice the Source Buffer fn slice(&self, start: usize, end: usize) -> &'a str; } /// Source of Characters from a `str` Slice struct StringSource { pub buff: &'a str } /// Implementation of the Source trait. impl Source for StringSource { fn at(&self, offset: usize) -> Option { self.buff[offset..].chars().nth(0).map(|ch| { (ch, offset + ch.len_utf8()) }) } fn slice(&self, start: usize, end: usize) -> &'a str { &self.buff[start..end] } } /// Token Iterator Implementation /// /// This token iterator takes a given source and steps through it returning string slices for each token struct TokenIter where S: Source, S: 'a { source: S, idx: usize, phantom: ::std::marker::PhantomData, } impl TokenIter where S: Source { /// Create a Token Iterator from a Source fn new(source: S) -> Self { TokenIter { source: source, idx: 0, phantom: ::std::marker::PhantomData, } } } /// Token Iterators implement `Iterator` impl Iterator for TokenIter where S: Source { type Item = &'a str; fn next(&mut self) -> Option { let ts = self.idx; self.source.at(ts).map(|(_ch,
- pattern minor 112d agoSimple array "manager"I'm new to Rust, coming from C++, and so to increase my knowledge of Rust I made a small program to manage an array. You can add, insert, delete, print and more an array or its elements. I don't really care much about performance at this point, but more on readability, good practices and so on. So, what could I have done better? ``` use std::io; fn get_element() -> i64 { println!("Enter the element: "); let mut element = String::new(); io::stdin().read_line(&mut element).expect("Failed to read line!"); match element.trim().parse() { Ok(num) => num, Err(_) => { println!("Invalid number! Try again."); get_element() } } } fn get_index(length: usize) -> usize { println!("Enter the index: "); let mut index = String::new(); io::stdin().read_line(&mut index).expect("Failed to read line!"); match index.trim().parse() { Ok(index) if index index, Ok(index) => { println!("Invalid index! {} is not in range [0, {})! Try again.", index, length); get_index(length) }, Err(_) => { println!("Invalid number! Try again."); get_index(length) } } } fn main() { println!("Welcome to the Vector application!"); let mut vec: Vec = Vec::new(); loop { println!("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-"); println!("What do you want to do?"); println!("1. Clear the vector"); println!("2. Add element"); println!("3. Insert element at pos"); println!("4. Delete an element at index"); println!("5. Print an element"); println!("6. Print vector"); println!("*. Exit"); let mut input = String::new(); io::stdin().read_line(&mut input).expect("Failed to read line"); let input: u8 = match input.trim().parse() { Ok(num) if num num, Ok(num) => { println!("{} is
- pattern minor 112d agoA simple maze generator written in RustI have been interested in trying Rust in a long time, and I finally got around to sit down and start reading "The Book". I have not finished yet, so there are probably a few features that I could have used, but I didn't know about. Anyway, the purpose of this program is to generate a maze (using the simplest "Randomized DFS" algorithm). Since the main goal for me was to practice the language, I tried to make the program as "idiomatic" as possible. The main thing that still bothers me is all those type conversions between the signed and unsigned types. Since this is my first Rust program, I am mainly just looking for feedback on anything that could be considered "bad code", or parts that could be improved in any way. ``` extern crate rand; extern crate image; use std::io::Write; use rand::Rng; #[derive(Clone, PartialEq)] enum Cell { Blocked, Free, } fn make_odd(mut t: (usize, usize)) -> (usize, usize) { let o = |v: &mut usize| if *v%2==0{*v+=1}; o(&mut t.0); o(&mut t.1); t } fn gen(s: (usize, usize)) -> Vec> { let mut t = vec![vec![Cell::Blocked; s.1]; s.0]; let mut stack = Vec::::new(); let c = make_odd((s.0/2, s.1/2)); stack.push((c.0 as isize, c.1 as isize)); t[c.0][c.1] = Cell::Free; let mut dirs: [(isize, isize); 4] = [(2, 0), (-2, 0), (0, 2), (0, -2)]; let mut rng = rand::thread_rng(); 'o: while let Some(&(x, y)) = stack.last() { rng.shuffle(&mut dirs); for i in 0..4 { let (dx, dy) = dirs[i]; let (nx, ny) = (x+dx, y+dy); if nx = (s.0 as isize) || ny >= (s.1 as isize) { continue; } if t[nx as usize][ny as usize] != Cell::Free { stack.push((nx, ny)); t[nx as usize][ny as usize] = Cell::Free; t[(x+dx/2) as usize][(y+dy/2) as usize] = Cell::Free; continue 'o; } } stack.pop(); } t[0][1] = Cell::Free; t[s.0-1][s.1-2] = Cell::Free; t } fn p
- pattern minor 112d agoConversion of Haskell CBOR decoding code into RustI was interested in converting the following Haskell code, that does decoding of CBOR into Rust: `module Main where import Data.Word import Data.Bits import Control.Monad.Trans.Except data Value = I Int deriving (Show) read_int xs size = f xs size 0 where f _ 0 acc = return (I acc) f [] _ acc = throwE () f (x:xs) n acc = f xs (n - 1) (acc `shiftL` 8 .|. fromIntegral x) cbor_decode (x:xs) | x >= 0x00 && x = 0x18 && x I ended up with the following: `use Value::*; #[derive(Debug)] enum Value { I(i64), } fn read_int(buf: &[u8], size: usize) -> Result { fn f(buf: &[u8], size: usize, acc: i64) -> Result { if size == 0 { Ok(I(acc)) } else if buf.len() == 0 { Err(()) } else { f(&buf[1..], size - 1, acc Result { match buf[0] { 0x00 ... 0x17 => Ok(I(buf[0] as i64)), 0x18 ... 0x1b => read_int(&buf[1..], (buf[0] - 0x17) as usize), _ => Err(()), } } fn main() { let x = vec!(0x1a, 1, 0, 0); let y = cbor_decode(&x); println!("{:?}", y); } ` Is this considered good Rust?
- pattern minor 112d agoArticle date extractorI am quite new to Rust and this is my first library written in it. It's an article date extractor heavily inspired by the original Python library as well as its Haskell port. It is fairly small and most of the logic was taken from the Python library. I want to make sure my Rust code is idiomatic. This is extract_date.rs: ``` use regex::Regex; use chrono::NaiveDate; use reqwest; use std::io::Read; use select::document::Document; use select::predicate::{Name, Attr}; use rustc_serialize::json::Json; use errors::*; // Some formats borrowed from https://github.com/amir/article-date-extractor static FMTS: &'static [&str] = &["%A, %B %e, %Y", "%Y-%m-%dT%H:%M:%S%:z", "/%Y/%m/%d/", "/%Y/%d/%m/", "%Y-%m-%d", "%B %e, %Y", "%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%SZ", "%B %k, %Y, %H:%M %p", "%Y-%m-%d %H:%M:%S.000000"]; // Use lazy_static to ensure we only compile the regex once lazy_static! { // Regex by Newspaper3k - https://github.com/codelucas/newspaper/blob/master/newspaper/urls.py static ref RE: Regex = Regex::new(r"([\./\-_]{0,1}(19|20)\d{2})[\./\-_]{0,1}(([0-3]{0,1}[0-9][\./\-_])|(\w{3,5}[\./\-_]))([0-3]{0,1}[0-9][\./\-]{0,1})").unwrap(); } // Parse the date, trying out each format fn parse_date(input: &str) -> Result { let mut result: Result = Err("None of the formats matched the date".into()); 'outer: for fmt in FMTS { if let Ok(v) = NaiveDate::parse_from_str(input, fmt) { { result = Ok(v); break 'outer; } } } result } // Extract date from a URL fn extract_from_url(url: &str) -> Option { if let Some(val) = RE.find(url) { return Some(val.as_str().to_string()
- pattern minor 112d agoPrime Sieve in Rust (Sieve of Eratosthenes)I am learning Rust and I decided to make a prime sieve program. It works and has comparable performance to my equivalent C program. I am new to Rust so I would like some feedback on my code. In particular, is my code in the correct Rust style? I am aware of some changes to make the algorithm faster, but I would prefer feedback on the style of Rust code instead. ``` use std::env; use std::fs::File; use std::io::{Write, BufWriter}; fn prime_sieve(n: usize, ofile: &String) -> u32 { let f = File::create(ofile).expect("Unable to create file"); let mut f = BufWriter::new(f); let mut prime_mask: Vec = vec![true;n]; prime_mask[0] = false; prime_mask[1] = false; let mut p = 2; // First prime number let mut count = 0; // Total number of primes found let mut i; // Main sieve loop while p = env::args().collect(); let n: usize = args[1] .trim() .parse() .expect("Wanted a number"); let ofile = &args[2]; let np = prime_sieve(n,ofile); println!("Found {} primes less than {}. Wrote to {}", np, n, &args[2]); } ```
- pattern minor 112d agoARC 067 - read ints and find the best choicesI just started learning Rust, and this is my solution to a problem from Atcoder's Regular Contest #067, D - Walk and Teleport. The problem can be summarized as follows: - There are N towns in a line, and you are about to visit all of them. - Town i is located at the point with coordinate xi. - You can travel either by walking or by teleporting. (You can combine them) - Walking costs you a * |Δx|, where a is a constant given and Δx is the distance you are about to travel. - Teleporing to any location costs you b, regardless of the distance you travel. - Given a, b and a sorted list of coordinates (xi), find the minimum cost to travel all towns. Input is given in the form of `N a b x1 x2 ... xN ` where N is the number of cities and a, b, xi is what described above. Again, xi is sorted. All a, b, xi are integers in the range of [1, 109]. My speculation is that you can just travel from left to right, and choose the cheaper way to travel to the next town (a*(xj+1-xj) versus b). This is my code. ``` use std::io; use std::cmp::min; fn main (){ let input_one = read_ints(); let a = input_one[1]; let b = input_one[2]; let xs = read_ints(); println!("{}", solve(&a,&b,&xs)); } fn distances(xs:&[u64]) -> Vec{ // Find the distances between adjacent towns xs.iter().zip(xs.iter().skip(1)).map(|(a,b)| b-a).collect() } fn solve(a:&u64, b:&u64, xs:&[u64]) -> u64 { let dists = distances(xs); dists.iter().fold(0, |acc,dist| { acc + min(a*dist, *b) }) } fn read_ints() -> Vec { get_line().trim().split_whitespace().map(|n| n.parse().unwrap()).collect() } fn get_line() -> String { let mut buf = String::new(); io::stdin().read_line(&mut buf).ok(); buf } ``` As I'm new to Rust, my main concern is the idiomaticness of the code. I've been writing Haskell and Python and there are many "it works but I'm not sure if I'm doing it right" moments. (Like, `&[u64]`'s were `&Vec` just until I was about to post this question.)