Coder Social home page Coder Social logo

a-range's People

Contributors

eignnx avatar killercup avatar kimsnj avatar sindreij avatar thinkchaos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

a-range's Issues

Move crate-level docs into Readme and include it

It's a bit of weird dance right now, but we can include the content of the README.md file as documentation on nightly.

  • Move content of crate-level docs to README.md
  • Include the readme
    • Behind a new nighty cargo feature
    • Actually include it (like this)
    • Enable the nightly feature on docs.rs (like this)

Add docs with non-integer index types

Either the crate-level or the Range docs should describe how to write a custom type that can be used as an index. (This will require you to impl num_traits::One for the custom type, for example.)

Validate inputs in constructor

  • from(n).up_to(n-1) should fail
  • from(n).down_to(n+1) should fail
  • What should from(n).up_to(n) and from(n).down_to(n+1) do? Nothing?

Make unit tests for std::ops::Range converstion doc tests

To understand how Range:: work, it helps to see example code in the documentation. These examples should also work as doc tests (you can liberally hide the assertion lines if you want).

Add at least one example to

  • Range::as_std_range()
  • Range::as_std_range_inclusive()
  • Into<std::ops::Range<Idx>> for Range
  • Into<std::ops::RangeInclusive<Idx>> for Range

Currently, there are these unit tests:

a-range/src/lib.rs

Lines 371 to 391 in ce391ed

#[test]
fn as_std_range() {
let r = from(10).up_to(14);
let u: Vec<i32> = r.as_std_range().into_iter().take(10).collect();
let v: Vec<i32> = r.into_iter().take(10).collect();
assert_eq!(u, vec![10, 11, 12, 13, 14]);
assert_eq!(v, vec![10, 11, 12, 13, 14]);
}
#[test]
fn as_std_range_inclusive() {
let r = from(10).up_to(14);
let u: Vec<i32> = r.as_std_range_inclusive().into_iter().take(10).collect();
let v: Vec<i32> = r.into_iter().take(10).collect();
assert_eq!(u, vec![10, 11, 12, 13, 14]);
assert_eq!(v, vec![10, 11, 12, 13, 14]);
}

You can move this code into the doc tests, and remove these unit tests afterwards.

.up_to_infinity()

Make this work:

let x = a_range::from(4).up_to_infinity();
let some_numbers: Vec<i32> = x.into_iter().take(100).collect();

Add documentation and doc test for `from(i).up_to(i)` case

In #6, we added

a-range/src/lib.rs

Lines 405 to 417 in ce391ed

#[test]
fn up_to_equivalent_val() {
let r = from(10).up_to(10);
assert_eq!(r.to_vec(), vec![10]);
}
#[test]
fn down_to_equivalent_val() {
let r = from(10).down_to(10);
assert_eq!(r.to_vec(), vec![10]);
}

We should

  • document this behavior (either in the crate-level docs or in the docs for up_to/down_to) and
  • make these unit tests doc tests

Add `.iter` method on `Range`

  • for i in a_range::from(1).up_to(5).iter() { let _i: &i32 = i; } compiles
  • Tests added as doc tests on iter() method

Copy semantics/Trait for a_range::From

::From should have Copy semantics or Traits available (either derived or implemented by us).

Since multiple ranges can have a single starting point, it makes sense for a user to be able to reuse a ::From object.

An example:

let start = a_range::from(10);

let up_range = start.up_to(13); // [10, 11, 12, 13]

let down_range = start.down_to(8); // No copy semantics, so this fails to compile.

Formally, this is the kind of compile error I get right now:

error[E0382]: use of moved value: `x`
 --> src/lib.rs:27:18
  |
6 | let up_range = x.up_to(10);
  |                - value moved here
7 | let down_range = x.down_to(10);
  |                  ^ value used here after move
  |
  = note: move occurs because `x` has type `a_range::From<i32>`, which does not implement the `Copy` trait

Proposal: Make `Direction` unsealed to enable multidimensional extensions

Having Direction avaliable publicly means that this library could be used in situations where there are more than one dimension. The following is a contrived example:

struct Vector2 { x: u32, y: u32 };

struct Diagonal45Deg;

impl Direction<Vector2> for Diagonal45Deg {
  fn step(i: &mut Vector2) {
    *i.x += 1;
    *i.y += 1;
  }
}

fn main() {
  let range = a_range::from(Vector2 { 0, 1 }).to_diag(Vector2 { 10, 11 });
}

The example above is not fully functional because we have not defined how two Vector2 should be compared (discussed below), but I just wanted to show an example usage.

A difficulty with multiple dimensions is defining when a range should end. When there is only a single dimention, its easy to check if a value is greater/smaller than another and make conclusions based on that. E.g one is not allowed to do a_range::from(5).to(0) because 5 > 0. Using multidimensional directions the destination might be harder to define because of multiple conditions. With the current implementation we need to define some way of comparing two Vector2, which can be done in multiple ways. In this situation we probably want to compare the magnitude. However this would lead to the following being a valid range a_range::from(Vector2 { 1, 1 }).to_diag(Vector2 { -2, -2 }) because the magnitude of the second Vector2 is still larger than the initial, despite it pointing in the opposite direction.

This could be solved by rather having a signature like a_range::from(Vector2 { 1, 1 }).take_diag(5), which would generate a range which gives back 5 vectors. This is already, in a sense, a part of the library using up_to_infinity followed by a .iter().take(5). I think it would make the library more generic to rather use a countdown-field than the current to field, especially if adding multidimensional ranges.

This might be an ambitious addtion which makes the library perhaps a bit too generic. Maybe then adding this library would be "harder" than just manually implementing a special iterator which performs the given task.

Thoughts/Comments?

Add doc tests to Panic documentation

We recently added these docs:

a-range/src/lib.rs

Lines 54 to 58 in ce391ed

/// Construct a [Range] that counts up to the given item.
///
/// # Panics
///
/// This function will panic when trying to create a [Range] where the upper bound is less than the lower bound.

This behavior is tested in this unit test:

a-range/src/lib.rs

Lines 393 to 397 in ce391ed

#[test]
#[should_panic]
fn fail_up_to_invalid_range() {
from(40).up_to(39);
}

It is also possible for this to become a doc test (as I've just found out), which would make this more visible.

  • Turn fail_up_to_invalid_range and fail_down_to_invalid_range tests into doc tests

Doc tests for `Range::collect()`

Ranges implement collect() and to_vec() methods. To illustrate how they can be used, we should add examples to their documentation. These examples should also work as doc tests for the methods.

  • For both upward and downward ranges, add an example…
    • for collecting into a Vec, with a note linking to to_vec()
    • for to_vec
    • for collecting into a non-vec data structure (pick one you like from here)
  • Remove unit tests that are now covered by the doc tests (like these)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.