Fetching and storing new reddit posts

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












I've created a small tool that fetches and stores the newest self-posts from a specific subreddit. The posts are stored in a redis store.



I'm going to write another couple of applications at a future date that will read from the redis store. I will want to be able to pick from the stored posts at random.



This is one of my first forays into writing something that's useful to me in rust, so I'd love some feedback.



#[macro_use]
extern crate serde_derive;

extern crate reqwest;
extern crate serde;
extern crate serde_json;
extern crate redis;

use redis::PipelineCommands;

#[derive(Deserialize)]
struct RedditResponse
data: Data,


#[derive(Deserialize)]
struct Data
children: Vec<Post>,


#[derive(Deserialize)]
struct Post
data: PostData,


#[derive(Deserialize)]
struct PostData
id: String,
is_self: bool,
title: String,


fn main()
let self_posts = match get_posts(20)
Ok(v) => v,
Err(e) => panic!("Failed to fetch new posts: :?", e),
;

let redis_client = match redis::Client::open("redis://127.0.0.1")
Ok(c) => c,
Err(e) => panic!("Unable to create the store client: :?", e),
;

let redis_conn = match redis_client.get_connection()
Ok(c) => c,
Err(e) => panic!("Unable to retrieve the connection to the store: :?", e),
;

match add_posts_to_store(redis_conn, self_posts)
Ok(n) => println!("Stored posts.", n),
Err(e) => panic!("Could not store posts: :?", e),
;


fn get_posts(num: usize) -> reqwest::Result<Vec<Post>> p

fn add_posts_to_store(store: redis::Connection, posts: Vec<Post>) -> redis::RedisResult<usize>
let mut pipe = redis::pipe();

for p in &posts
pipe.set(&p.data.id, &p.data.title).ignore();


pipe.query(&store)?;

Ok(posts.len())







share|improve this question

























    up vote
    4
    down vote

    favorite












    I've created a small tool that fetches and stores the newest self-posts from a specific subreddit. The posts are stored in a redis store.



    I'm going to write another couple of applications at a future date that will read from the redis store. I will want to be able to pick from the stored posts at random.



    This is one of my first forays into writing something that's useful to me in rust, so I'd love some feedback.



    #[macro_use]
    extern crate serde_derive;

    extern crate reqwest;
    extern crate serde;
    extern crate serde_json;
    extern crate redis;

    use redis::PipelineCommands;

    #[derive(Deserialize)]
    struct RedditResponse
    data: Data,


    #[derive(Deserialize)]
    struct Data
    children: Vec<Post>,


    #[derive(Deserialize)]
    struct Post
    data: PostData,


    #[derive(Deserialize)]
    struct PostData
    id: String,
    is_self: bool,
    title: String,


    fn main()
    let self_posts = match get_posts(20)
    Ok(v) => v,
    Err(e) => panic!("Failed to fetch new posts: :?", e),
    ;

    let redis_client = match redis::Client::open("redis://127.0.0.1")
    Ok(c) => c,
    Err(e) => panic!("Unable to create the store client: :?", e),
    ;

    let redis_conn = match redis_client.get_connection()
    Ok(c) => c,
    Err(e) => panic!("Unable to retrieve the connection to the store: :?", e),
    ;

    match add_posts_to_store(redis_conn, self_posts)
    Ok(n) => println!("Stored posts.", n),
    Err(e) => panic!("Could not store posts: :?", e),
    ;


    fn get_posts(num: usize) -> reqwest::Result<Vec<Post>> p

    fn add_posts_to_store(store: redis::Connection, posts: Vec<Post>) -> redis::RedisResult<usize>
    let mut pipe = redis::pipe();

    for p in &posts
    pipe.set(&p.data.id, &p.data.title).ignore();


    pipe.query(&store)?;

    Ok(posts.len())







    share|improve this question





















      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I've created a small tool that fetches and stores the newest self-posts from a specific subreddit. The posts are stored in a redis store.



      I'm going to write another couple of applications at a future date that will read from the redis store. I will want to be able to pick from the stored posts at random.



      This is one of my first forays into writing something that's useful to me in rust, so I'd love some feedback.



      #[macro_use]
      extern crate serde_derive;

      extern crate reqwest;
      extern crate serde;
      extern crate serde_json;
      extern crate redis;

      use redis::PipelineCommands;

      #[derive(Deserialize)]
      struct RedditResponse
      data: Data,


      #[derive(Deserialize)]
      struct Data
      children: Vec<Post>,


      #[derive(Deserialize)]
      struct Post
      data: PostData,


      #[derive(Deserialize)]
      struct PostData
      id: String,
      is_self: bool,
      title: String,


      fn main()
      let self_posts = match get_posts(20)
      Ok(v) => v,
      Err(e) => panic!("Failed to fetch new posts: :?", e),
      ;

      let redis_client = match redis::Client::open("redis://127.0.0.1")
      Ok(c) => c,
      Err(e) => panic!("Unable to create the store client: :?", e),
      ;

      let redis_conn = match redis_client.get_connection()
      Ok(c) => c,
      Err(e) => panic!("Unable to retrieve the connection to the store: :?", e),
      ;

      match add_posts_to_store(redis_conn, self_posts)
      Ok(n) => println!("Stored posts.", n),
      Err(e) => panic!("Could not store posts: :?", e),
      ;


      fn get_posts(num: usize) -> reqwest::Result<Vec<Post>> p

      fn add_posts_to_store(store: redis::Connection, posts: Vec<Post>) -> redis::RedisResult<usize>
      let mut pipe = redis::pipe();

      for p in &posts
      pipe.set(&p.data.id, &p.data.title).ignore();


      pipe.query(&store)?;

      Ok(posts.len())







      share|improve this question











      I've created a small tool that fetches and stores the newest self-posts from a specific subreddit. The posts are stored in a redis store.



      I'm going to write another couple of applications at a future date that will read from the redis store. I will want to be able to pick from the stored posts at random.



      This is one of my first forays into writing something that's useful to me in rust, so I'd love some feedback.



      #[macro_use]
      extern crate serde_derive;

      extern crate reqwest;
      extern crate serde;
      extern crate serde_json;
      extern crate redis;

      use redis::PipelineCommands;

      #[derive(Deserialize)]
      struct RedditResponse
      data: Data,


      #[derive(Deserialize)]
      struct Data
      children: Vec<Post>,


      #[derive(Deserialize)]
      struct Post
      data: PostData,


      #[derive(Deserialize)]
      struct PostData
      id: String,
      is_self: bool,
      title: String,


      fn main()
      let self_posts = match get_posts(20)
      Ok(v) => v,
      Err(e) => panic!("Failed to fetch new posts: :?", e),
      ;

      let redis_client = match redis::Client::open("redis://127.0.0.1")
      Ok(c) => c,
      Err(e) => panic!("Unable to create the store client: :?", e),
      ;

      let redis_conn = match redis_client.get_connection()
      Ok(c) => c,
      Err(e) => panic!("Unable to retrieve the connection to the store: :?", e),
      ;

      match add_posts_to_store(redis_conn, self_posts)
      Ok(n) => println!("Stored posts.", n),
      Err(e) => panic!("Could not store posts: :?", e),
      ;


      fn get_posts(num: usize) -> reqwest::Result<Vec<Post>> p

      fn add_posts_to_store(store: redis::Connection, posts: Vec<Post>) -> redis::RedisResult<usize>
      let mut pipe = redis::pipe();

      for p in &posts
      pipe.set(&p.data.id, &p.data.title).ignore();


      pipe.query(&store)?;

      Ok(posts.len())









      share|improve this question










      share|improve this question




      share|improve this question









      asked May 24 at 13:49









      tverghis

      1235




      1235




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          The pattern



          match some_result 
          Ok(v) => v,
          Err(e) => panic!("message: :?", e),



          is exactly what expect does for you. We can get a somewhat leaner main if we use that instead:



          fn main() 
          let self_posts = get_posts(20).expect("Failed to fetch new posts");

          let redis_client =
          redis::Client::open("redis://127.0.0.1").expect("Unable to create the store client");

          let redis_conn = redis_client
          .get_connection()
          .expect("Unable to retrieve the connection to the store");

          match add_posts_to_store(redis_conn, self_posts)
          Ok(n) => println!("Stored posts.", n),
          Err(e) => panic!("Could not store posts: :?", e),
          ;



          Somewhat, because the error messages lead to long lines and rustfmt doesn't like that.



          However, keep in mind that while panic is great for developers, it's a system that should be used for unrecoverable errors, bugs that you cannot handle or anticipate. When you panic!, you generate an error message that's helpful for programmers, but not for users:



          thread 'main' panicked at 'Unable to retrieve the connection to the store: .......', src/main.rs:.....
          note: Run with `RUST_BACKTRACE=1` for a backtrace.


          Instead, stderr should get used. The Rust Book contains a section for error handling in its example I/O project which you can use for inspiration. But if you never intend to distribute your reddit/redis updater, feel free to use panic! or .expect("...").



          Other than that, the turbofish syntax at collect::<Vec<Post>>() isn't necessary, since its inferred by the return type. Also, you can traverse p in posts instead of &p in &posts since you don't want to use the Vec afterwards, you just have to save the posts.len() beforehand.



          However, you probably want to use store : &redis::Connection in add_posts_to_store if you want to reuse the connection. Also, you usually want to derive some of the standard traits, for example Debug. Again, that depends on whether you will use your structs in another context, but if you ever publish your package it's very recommended to derive all possible standard traits (Debug, PartialEq, Eq, PartialOrd, Ord, Clone and maybe Hash in your case).






          share|improve this answer





















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195089%2ffetching-and-storing-new-reddit-posts%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote



            accepted










            The pattern



            match some_result 
            Ok(v) => v,
            Err(e) => panic!("message: :?", e),



            is exactly what expect does for you. We can get a somewhat leaner main if we use that instead:



            fn main() 
            let self_posts = get_posts(20).expect("Failed to fetch new posts");

            let redis_client =
            redis::Client::open("redis://127.0.0.1").expect("Unable to create the store client");

            let redis_conn = redis_client
            .get_connection()
            .expect("Unable to retrieve the connection to the store");

            match add_posts_to_store(redis_conn, self_posts)
            Ok(n) => println!("Stored posts.", n),
            Err(e) => panic!("Could not store posts: :?", e),
            ;



            Somewhat, because the error messages lead to long lines and rustfmt doesn't like that.



            However, keep in mind that while panic is great for developers, it's a system that should be used for unrecoverable errors, bugs that you cannot handle or anticipate. When you panic!, you generate an error message that's helpful for programmers, but not for users:



            thread 'main' panicked at 'Unable to retrieve the connection to the store: .......', src/main.rs:.....
            note: Run with `RUST_BACKTRACE=1` for a backtrace.


            Instead, stderr should get used. The Rust Book contains a section for error handling in its example I/O project which you can use for inspiration. But if you never intend to distribute your reddit/redis updater, feel free to use panic! or .expect("...").



            Other than that, the turbofish syntax at collect::<Vec<Post>>() isn't necessary, since its inferred by the return type. Also, you can traverse p in posts instead of &p in &posts since you don't want to use the Vec afterwards, you just have to save the posts.len() beforehand.



            However, you probably want to use store : &redis::Connection in add_posts_to_store if you want to reuse the connection. Also, you usually want to derive some of the standard traits, for example Debug. Again, that depends on whether you will use your structs in another context, but if you ever publish your package it's very recommended to derive all possible standard traits (Debug, PartialEq, Eq, PartialOrd, Ord, Clone and maybe Hash in your case).






            share|improve this answer

























              up vote
              3
              down vote



              accepted










              The pattern



              match some_result 
              Ok(v) => v,
              Err(e) => panic!("message: :?", e),



              is exactly what expect does for you. We can get a somewhat leaner main if we use that instead:



              fn main() 
              let self_posts = get_posts(20).expect("Failed to fetch new posts");

              let redis_client =
              redis::Client::open("redis://127.0.0.1").expect("Unable to create the store client");

              let redis_conn = redis_client
              .get_connection()
              .expect("Unable to retrieve the connection to the store");

              match add_posts_to_store(redis_conn, self_posts)
              Ok(n) => println!("Stored posts.", n),
              Err(e) => panic!("Could not store posts: :?", e),
              ;



              Somewhat, because the error messages lead to long lines and rustfmt doesn't like that.



              However, keep in mind that while panic is great for developers, it's a system that should be used for unrecoverable errors, bugs that you cannot handle or anticipate. When you panic!, you generate an error message that's helpful for programmers, but not for users:



              thread 'main' panicked at 'Unable to retrieve the connection to the store: .......', src/main.rs:.....
              note: Run with `RUST_BACKTRACE=1` for a backtrace.


              Instead, stderr should get used. The Rust Book contains a section for error handling in its example I/O project which you can use for inspiration. But if you never intend to distribute your reddit/redis updater, feel free to use panic! or .expect("...").



              Other than that, the turbofish syntax at collect::<Vec<Post>>() isn't necessary, since its inferred by the return type. Also, you can traverse p in posts instead of &p in &posts since you don't want to use the Vec afterwards, you just have to save the posts.len() beforehand.



              However, you probably want to use store : &redis::Connection in add_posts_to_store if you want to reuse the connection. Also, you usually want to derive some of the standard traits, for example Debug. Again, that depends on whether you will use your structs in another context, but if you ever publish your package it's very recommended to derive all possible standard traits (Debug, PartialEq, Eq, PartialOrd, Ord, Clone and maybe Hash in your case).






              share|improve this answer























                up vote
                3
                down vote



                accepted







                up vote
                3
                down vote



                accepted






                The pattern



                match some_result 
                Ok(v) => v,
                Err(e) => panic!("message: :?", e),



                is exactly what expect does for you. We can get a somewhat leaner main if we use that instead:



                fn main() 
                let self_posts = get_posts(20).expect("Failed to fetch new posts");

                let redis_client =
                redis::Client::open("redis://127.0.0.1").expect("Unable to create the store client");

                let redis_conn = redis_client
                .get_connection()
                .expect("Unable to retrieve the connection to the store");

                match add_posts_to_store(redis_conn, self_posts)
                Ok(n) => println!("Stored posts.", n),
                Err(e) => panic!("Could not store posts: :?", e),
                ;



                Somewhat, because the error messages lead to long lines and rustfmt doesn't like that.



                However, keep in mind that while panic is great for developers, it's a system that should be used for unrecoverable errors, bugs that you cannot handle or anticipate. When you panic!, you generate an error message that's helpful for programmers, but not for users:



                thread 'main' panicked at 'Unable to retrieve the connection to the store: .......', src/main.rs:.....
                note: Run with `RUST_BACKTRACE=1` for a backtrace.


                Instead, stderr should get used. The Rust Book contains a section for error handling in its example I/O project which you can use for inspiration. But if you never intend to distribute your reddit/redis updater, feel free to use panic! or .expect("...").



                Other than that, the turbofish syntax at collect::<Vec<Post>>() isn't necessary, since its inferred by the return type. Also, you can traverse p in posts instead of &p in &posts since you don't want to use the Vec afterwards, you just have to save the posts.len() beforehand.



                However, you probably want to use store : &redis::Connection in add_posts_to_store if you want to reuse the connection. Also, you usually want to derive some of the standard traits, for example Debug. Again, that depends on whether you will use your structs in another context, but if you ever publish your package it's very recommended to derive all possible standard traits (Debug, PartialEq, Eq, PartialOrd, Ord, Clone and maybe Hash in your case).






                share|improve this answer













                The pattern



                match some_result 
                Ok(v) => v,
                Err(e) => panic!("message: :?", e),



                is exactly what expect does for you. We can get a somewhat leaner main if we use that instead:



                fn main() 
                let self_posts = get_posts(20).expect("Failed to fetch new posts");

                let redis_client =
                redis::Client::open("redis://127.0.0.1").expect("Unable to create the store client");

                let redis_conn = redis_client
                .get_connection()
                .expect("Unable to retrieve the connection to the store");

                match add_posts_to_store(redis_conn, self_posts)
                Ok(n) => println!("Stored posts.", n),
                Err(e) => panic!("Could not store posts: :?", e),
                ;



                Somewhat, because the error messages lead to long lines and rustfmt doesn't like that.



                However, keep in mind that while panic is great for developers, it's a system that should be used for unrecoverable errors, bugs that you cannot handle or anticipate. When you panic!, you generate an error message that's helpful for programmers, but not for users:



                thread 'main' panicked at 'Unable to retrieve the connection to the store: .......', src/main.rs:.....
                note: Run with `RUST_BACKTRACE=1` for a backtrace.


                Instead, stderr should get used. The Rust Book contains a section for error handling in its example I/O project which you can use for inspiration. But if you never intend to distribute your reddit/redis updater, feel free to use panic! or .expect("...").



                Other than that, the turbofish syntax at collect::<Vec<Post>>() isn't necessary, since its inferred by the return type. Also, you can traverse p in posts instead of &p in &posts since you don't want to use the Vec afterwards, you just have to save the posts.len() beforehand.



                However, you probably want to use store : &redis::Connection in add_posts_to_store if you want to reuse the connection. Also, you usually want to derive some of the standard traits, for example Debug. Again, that depends on whether you will use your structs in another context, but if you ever publish your package it's very recommended to derive all possible standard traits (Debug, PartialEq, Eq, PartialOrd, Ord, Clone and maybe Hash in your case).







                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered May 24 at 18:10









                Zeta

                14.3k23267




                14.3k23267






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195089%2ffetching-and-storing-new-reddit-posts%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation