pub fn level(difficulty: u64, page_no: usize) -> HttpResponse {
    if difficulty >= 9 {
        return success()
    }

    let mut rng = rand::thread_rng();

    // lvl 5 random wait
    if difficulty >= 4 && difficulty <= 5 { // Don't wait when images are part of the response
        // random sleep
        if rng.gen_bool(0.25) {
            sleep(Duration::from_millis(rng.gen_range(1500, 20000)))
        };
    }

    // lvl 4 random errors
    if difficulty >= 4 {
        if rng.gen_bool(0.25) {
            return match rng.gen_range(0, 5) {
                0 => HttpResponse::InternalServerError().finish(),
                1 => HttpResponse::TooManyRequests().finish(),
                2 => HttpResponse::ServiceUnavailable().finish(),
                3 => HttpResponse::InsufficientStorage().finish(),
                _ => HttpResponse::GatewayTimeout().finish(),
            };
        }
    }

    // lvl7 large page size
    let page_size = if difficulty >= 7 {
        HUGE_PAGE_SIZE
    } else {
        PAGE_SIZE
    };

    let before = format!("{{\"level\": {}, \"usages\": [", difficulty);
    let after = "]}".to_string();

    let it = iter::once::<Result<Bytes, ()>>(Ok(Bytes::copy_from_slice(before.as_bytes())))
        .chain(UsageGenerator::new(difficulty, page_no)
            .take(page_size)
            .enumerate()
            .map(move |(i, profile)| {
                if i < page_size - 1 {
                    format!("{},", profile.to_string())
                } else {
                    profile.to_string()
                }
            }).map(|raw| Ok(Bytes::copy_from_slice(raw.as_bytes())))
        ).chain(iter::once(Ok(Bytes::from(after))));

    HttpResponse::Ok().streaming(stream::iter(it))
}
/// Procedurally generate a response for the API. The response depends on the level number and the
/// and the requested pagenumber. The higher the level, the more the response is modified to make
/// the API harder to use.
/// The page number is used to procedurally generate the initial usage data, so that the API looks
/// realistic.
///
/// The data is generated on the fly and written as stream to the response. Hence it is not generated
/// ahead of time and the memory footprint is small.
///
/// # Difficulty levels
/// 1. sane and well structured JSON;
/// 2. randomized order of JSON properties;
/// 3. some fields are procedurally `null`ed and others are replaced by the empty string `""`;
/// 4. with p = 0.25, the response is delayed up to 20 seconds; with p = 0.25, the response contains an error;
/// 5. some timestamps are procedurally replaced by RFC 2822 or Unix timestamps instead of RFC 3339;
/// 6. some usages contain a large image, that artificially bloats the data;
/// 7. the page size is drastically increased (~ 1GB).
/// 9. a success message is printed
///
/// # Example
///
/// ```
/// use challenge::level;
/// let response = level(1, 8);
/// ```
/// The line above generates an HttpResponse with difficulty 1 (easy and sane JSON data).
///
Procedurally generate a response for the API. The response depends on the level number and the
and the requested pagenumber. The higher the level, the more the response is modified to make
the API harder to use.
The page number is used to procedurally generate the initial usage data, so that the API looks
realistic.

The data is generated on the fly and written as stream to the response. Hence it is not generated
ahead of time and the memory footprint is small.
Procedurally generate a response for the API . The response depends on the level number and the and the requested pagenumber . The higher the level the more the response is modified to make the API harder to use . The page number is used to procedurally generate the initial usage data so that the API looks realistic . The data is generated on the fly and written as stream to the response . Hence it is not generated ahead of time and the memory footprint is small .
pub fn level(difficulty: u64, page_no: usize) -> HttpResponse {
    if difficulty >= 9 {
        return success()
    }
    let mut rng = rand::thread_rng();
    // lvl 5 random wait
    if difficulty >= 4 && difficulty <= 5 { // Don't wait when images are part of the response
        // random sleep
        if rng.gen_bool(0.25) {
            sleep(Duration::from_millis(rng.gen_range(1500, 20000)))
        };
    }
    // lvl 4 random errors
    if difficulty >= 4 {
        if rng.gen_bool(0.25) {
            return match rng.gen_range(0, 5) {
                0 => HttpResponse::InternalServerError().finish(),
                1 => HttpResponse::TooManyRequests().finish(),
                2 => HttpResponse::ServiceUnavailable().finish(),
                3 => HttpResponse::InsufficientStorage().finish(),
                _ => HttpResponse::GatewayTimeout().finish(),
            };
        }
    }
    // lvl7 large page size
    let page_size = if difficulty >= 7 {
        HUGE_PAGE_SIZE
    } else {
        PAGE_SIZE
    };
    let before = format!("{{\"level\": {}, \"usages\": [", difficulty);
    let after = "]}".to_string();
    let it = iter::once::<Result<Bytes, ()>>(Ok(Bytes::copy_from_slice(before.as_bytes())))
        .chain(UsageGenerator::new(difficulty, page_no)
            .take(page_size)
            .enumerate()
            .map(move |(i, profile)| {
                if i < page_size - 1 {
                    format!("{},", profile.to_string())
                } else {
                    profile.to_string()
                }
            }).map(|raw| Ok(Bytes::copy_from_slice(raw.as_bytes())))
        ).chain(iter::once(Ok(Bytes::from(after))));
    HttpResponse::Ok().streaming(stream::iter(it))
}
pub fn level ( difficulty : u64 , page_no : usize ) -> HttpResponse { if difficulty >= 9 { return success ( ) } let mut rng = rand :: thread_rng ( ) ; // lvl 5 random wait if difficulty >= 4 && difficulty <= 5 { // Don't wait when images are part of the response // random sleep if rng . gen_bool ( 0.25 ) { sleep ( Duration :: from_millis ( rng . gen_range ( 1500 , 20000 ) ) ) } ; } // lvl 4 random errors if difficulty >= 4 { if rng . gen_bool ( 0.25 ) { return match rng . gen_range ( 0 , 5 ) { 0 => HttpResponse :: InternalServerError ( ) . finish ( ) , 1 => HttpResponse :: TooManyRequests ( ) . finish ( ) , 2 => HttpResponse :: ServiceUnavailable ( ) . finish ( ) , 3 => HttpResponse :: InsufficientStorage ( ) . finish ( ) , _ => HttpResponse :: GatewayTimeout ( ) . finish ( ) , } ; } } // lvl7 large page size let page_size = if difficulty >= 7 { HUGE_PAGE_SIZE } else { PAGE_SIZE } ; let before = format ! ( " \" \" \" \" " difficulty ) ; let after = " " . to_string ( ) ; let it = iter :: once :: < Result < Bytes , ( ) > > ( Ok ( Bytes :: copy_from_slice ( before . as_bytes ( ) ) ) ) . chain ( UsageGenerator :: new ( difficulty , page_no ) . take ( page_size ) . enumerate ( ) . map ( move | ( i , profile ) | { if i < page_size - 1 { format ! ( " " profile to_string ( ) ) } else { profile . to_string ( ) } } ) . map ( | raw | Ok ( Bytes :: copy_from_slice ( raw . as_bytes ( ) ) ) ) ) . chain ( iter :: once ( Ok ( Bytes :: from ( after ) ) ) ) ; HttpResponse :: Ok ( ) . streaming ( stream :: iter ( it ) ) }
Procedurally generate a response for the API.
Procedurally generate a response for the API .
difficulty
u64
page_no
usize
difficulty
u64
page_no
usize
difficulty levels
1. sane and well structured JSON;
2. randomized order of JSON properties;
3. some fields are procedurally `null`ed and others are replaced by the empty string `""`;
4. with p = 0.25, the response is delayed up to 20 seconds; with p = 0.25, the response contains an error;
5. some timestamps are procedurally replaced by RFC 2822 or Unix timestamps instead of RFC 3339;
6. some usages contain a large image, that artificially bloats the data;
7. the page size is drastically increased (~ 1GB).
9. a success message is printed
1 . sane and well structured JSON ; 2 . randomized order of JSON properties ; 3 . some fields are procedurally ` null ` ed and others are replaced by the empty string ` " " ` ; 4 . with p = 0 . 25 the response is delayed up to 20 seconds ; with p = 0 . 25 the response contains an error ; 5 . some timestamps are procedurally replaced by RFC 2822 or Unix timestamps instead of RFC 3339 ; 6 . some usages contain a large image that artificially bloats the data ; 7 . the page size is drastically increased ( ~ 1GB ) . 9 . a success message is printed
example
```
use challenge::level;
let response = level(1, 8);
```
The line above generates an HttpResponse with difficulty 1 (easy and sane JSON data).
` ` ` use challenge :: level ; let response = level ( 1 8 ) ; ` ` ` The line above generates an HttpResponse with difficulty 1 ( easy and sane JSON data ) .