aboutsummaryrefslogtreecommitdiffstats
path: root/rust/src
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/api_lib.rs34
-rw-r--r--rust/src/api_server.rs288
-rw-r--r--rust/src/bin/fatcat-tokio.rs67
-rw-r--r--rust/src/bin/show_creators.rs24
-rw-r--r--rust/src/lib.rs40
5 files changed, 423 insertions, 30 deletions
diff --git a/rust/src/api_lib.rs b/rust/src/api_lib.rs
new file mode 100644
index 00000000..cc8c2313
--- /dev/null
+++ b/rust/src/api_lib.rs
@@ -0,0 +1,34 @@
+//! Main library entry point for fatcat implementation.
+
+// Imports required by server library.
+// extern crate fatcat;
+// extern crate swagger;
+extern crate futures;
+extern crate chrono;
+#[macro_use]
+extern crate error_chain;
+
+mod server;
+
+mod errors {
+ error_chain!{}
+}
+
+pub use self::errors::*;
+use std::io;
+use hyper;
+use fatcat;
+
+pub struct NewService;
+
+impl hyper::server::NewService for NewService {
+ type Request = (hyper::Request, fatcat::Context);
+ type Response = hyper::Response;
+ type Error = hyper::Error;
+ type Instance = fatcat::server::Service<server::Server>;
+
+ /// Instantiate a new server.
+ fn new_service(&self) -> io::Result<Self::Instance> {
+ Ok(fatcat::server::Service::new(server::Server))
+ }
+}
diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs
new file mode 100644
index 00000000..16701b27
--- /dev/null
+++ b/rust/src/api_server.rs
@@ -0,0 +1,288 @@
+//! Server implementation of fatcat.
+
+#![allow(unused_imports)]
+
+use chrono;
+use futures::{self, Future};
+
+use std::collections::HashMap;
+
+use swagger;
+
+use fatcat_api::models;
+use fatcat_api::{Api, ApiError, ContainerIdGetResponse, ContainerLookupGetResponse,
+ ContainerPostResponse, Context, CreatorIdGetResponse, CreatorLookupGetResponse,
+ CreatorPostResponse, EditgroupIdAcceptPostResponse, EditgroupIdGetResponse,
+ EditgroupPostResponse, EditorUsernameChangelogGetResponse,
+ EditorUsernameGetResponse, FileIdGetResponse, FileLookupGetResponse,
+ FilePostResponse, ReleaseIdGetResponse, ReleaseLookupGetResponse,
+ ReleasePostResponse, WorkIdGetResponse, WorkPostResponse};
+
+#[derive(Copy, Clone)]
+pub struct Server;
+
+impl Api for Server {
+ fn container_id_get(
+ &self,
+ id: String,
+ context: &Context,
+ ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "container_id_get(\"{}\") - X-Span-ID: {:?}",
+ id,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn container_lookup_get(
+ &self,
+ issn: String,
+ context: &Context,
+ ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "container_lookup_get(\"{}\") - X-Span-ID: {:?}",
+ issn,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn container_post(
+ &self,
+ body: Option<models::ContainerEntity>,
+ context: &Context,
+ ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "container_post({:?}) - X-Span-ID: {:?}",
+ body,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn creator_id_get(
+ &self,
+ id: String,
+ context: &Context,
+ ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "creator_id_get(\"{}\") - X-Span-ID: {:?}",
+ id,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn creator_lookup_get(
+ &self,
+ orcid: String,
+ context: &Context,
+ ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "creator_lookup_get(\"{}\") - X-Span-ID: {:?}",
+ orcid,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn creator_post(
+ &self,
+ body: Option<models::CreatorEntity>,
+ context: &Context,
+ ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "creator_post({:?}) - X-Span-ID: {:?}",
+ body,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn editgroup_id_accept_post(
+ &self,
+ id: i32,
+ context: &Context,
+ ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "editgroup_id_accept_post({}) - X-Span-ID: {:?}",
+ id,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn editgroup_id_get(
+ &self,
+ id: i32,
+ context: &Context,
+ ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "editgroup_id_get({}) - X-Span-ID: {:?}",
+ id,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn editgroup_post(
+ &self,
+ context: &Context,
+ ) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "editgroup_post() - X-Span-ID: {:?}",
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn editor_username_changelog_get(
+ &self,
+ username: String,
+ context: &Context,
+ ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "editor_username_changelog_get(\"{}\") - X-Span-ID: {:?}",
+ username,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn editor_username_get(
+ &self,
+ username: String,
+ context: &Context,
+ ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "editor_username_get(\"{}\") - X-Span-ID: {:?}",
+ username,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn file_id_get(
+ &self,
+ id: String,
+ context: &Context,
+ ) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "file_id_get(\"{}\") - X-Span-ID: {:?}",
+ id,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn file_lookup_get(
+ &self,
+ sha1: String,
+ context: &Context,
+ ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "file_lookup_get(\"{}\") - X-Span-ID: {:?}",
+ sha1,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn file_post(
+ &self,
+ body: Option<models::FileEntity>,
+ context: &Context,
+ ) -> Box<Future<Item = FilePostResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "file_post({:?}) - X-Span-ID: {:?}",
+ body,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn release_id_get(
+ &self,
+ id: String,
+ context: &Context,
+ ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "release_id_get(\"{}\") - X-Span-ID: {:?}",
+ id,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn release_lookup_get(
+ &self,
+ doi: String,
+ context: &Context,
+ ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "release_lookup_get(\"{}\") - X-Span-ID: {:?}",
+ doi,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn release_post(
+ &self,
+ body: Option<models::ReleaseEntity>,
+ context: &Context,
+ ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "release_post({:?}) - X-Span-ID: {:?}",
+ body,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn work_id_get(
+ &self,
+ id: String,
+ context: &Context,
+ ) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "work_id_get(\"{}\") - X-Span-ID: {:?}",
+ id,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+
+ fn work_post(
+ &self,
+ body: Option<models::WorkEntity>,
+ context: &Context,
+ ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>> {
+ let context = context.clone();
+ println!(
+ "work_post({:?}) - X-Span-ID: {:?}",
+ body,
+ context.x_span_id.unwrap_or(String::from("<none>")).clone()
+ );
+ Box::new(futures::failed("Generic failure".into()))
+ }
+}
diff --git a/rust/src/bin/fatcat-tokio.rs b/rust/src/bin/fatcat-tokio.rs
new file mode 100644
index 00000000..cc603908
--- /dev/null
+++ b/rust/src/bin/fatcat-tokio.rs
@@ -0,0 +1,67 @@
+//! Main binary entry point for fatcat implementation.
+
+#![allow(missing_docs)]
+
+// Imports required by this file.
+extern crate fatcat;
+extern crate fatcat_api;
+extern crate hyper;
+extern crate swagger;
+//extern crate openssl;
+//extern crate native_tls;
+extern crate tokio_proto;
+//extern crate tokio_tls;
+extern crate clap;
+
+//use openssl::x509::X509_FILETYPE_PEM;
+//use openssl::ssl::{SslAcceptorBuilder, SslMethod};
+//use openssl::error::ErrorStack;
+use clap::{App, Arg};
+use hyper::server::Http;
+use swagger::auth::AllowAllAuthenticator;
+use tokio_proto::TcpServer;
+
+// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
+/*
+fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
+ let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
+
+ // Server authentication
+ ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
+ ssl.set_certificate_chain_file("examples/server-chain.pem")?;
+ ssl.check_private_key()?;
+
+ Ok(ssl)
+}
+*/
+
+/// Create custom server, wire it to the autogenerated router,
+/// and pass it to the web server.
+fn main() {
+ let matches = App::new("server")
+ .arg(
+ Arg::with_name("https")
+ .long("https")
+ .help("Whether to use HTTPS or not"),
+ )
+ .get_matches();
+
+ let service_fn = fatcat_api::server::auth::NewService::new(AllowAllAuthenticator::new(
+ fatcat::NewService,
+ "cosmo",
+ ));
+
+ let addr = "127.0.0.1:8080"
+ .parse()
+ .expect("Failed to parse bind address");
+ if matches.is_present("https") {
+ unimplemented!()
+ //let ssl = ssl().expect("Failed to load SSL keys");
+ //let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
+ //let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
+ //TcpServer::new(tokio_tls::proto::Server::new(Http::new(), tls_acceptor), addr).serve(service_fn);
+ } else {
+ // Using HTTP
+ TcpServer::new(Http::new(), addr).serve(service_fn);
+ }
+}
diff --git a/rust/src/bin/show_creators.rs b/rust/src/bin/show_creators.rs
deleted file mode 100644
index 968d2542..00000000
--- a/rust/src/bin/show_creators.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-
-extern crate fatcat;
-extern crate diesel;
-
-use self::fatcat::*;
-use self::models::*;
-use self::diesel::prelude::*;
-
-fn main() {
- use diesel_demo::database_schema::creators::dsl::*;
-
- let connection = establish_connection();
- let results = creators.filter(published.eq(true))
- .limit(5)
- .load::<CreatorRev>(&connection)
- .expect("Error loading creators");
-
- println!("Displaying {} creators", results.len());
- for creator in results {
- println!("{}", creator.title);
- println!("----------\n");
- println!("{}", creator.body);
- }
-}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 679b9ed3..ec7193e6 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -1,18 +1,46 @@
-
#[macro_use]
+extern crate fatcat_api;
+extern crate chrono;
extern crate diesel;
extern crate dotenv;
+extern crate futures;
+extern crate hyper;
+extern crate swagger;
+#[macro_use]
+extern crate error_chain;
-use diesel::prelude::*;
+pub mod api_server;
+
+mod errors {
+ error_chain!{}
+}
+
+pub use self::errors::*;
use diesel::pg::PgConnection;
+use diesel::prelude::*;
use dotenv::dotenv;
use std::env;
+use std::io;
+//use hyper;
+//use fatcat_api;
pub fn establish_connection() -> PgConnection {
dotenv().ok();
- let database_url = env::var("DATABASE_URL")
- .expect("DATABASE_URL must be set");
- PgConnection::establish(&database_url)
- .expect(&format!("Error connecting to {}", database_url))
+ let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
+ PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
+}
+
+pub struct NewService;
+
+impl hyper::server::NewService for NewService {
+ type Request = (hyper::Request, fatcat_api::Context);
+ type Response = hyper::Response;
+ type Error = hyper::Error;
+ type Instance = fatcat_api::server::Service<api_server::Server>;
+
+ /// Instantiate a new server.
+ fn new_service(&self) -> io::Result<Self::Instance> {
+ Ok(fatcat_api::server::Service::new(api_server::Server))
+ }
}