Skip to content
This repository has been archived by the owner on Jun 7, 2022. It is now read-only.

Commit

Permalink
http module is fully generic over SemanticEngine
Browse files Browse the repository at this point in the history
The /find_definition and /list_completions handlers now longer assume
and create a Racer for every request. A SemanticEngine instance is now
passed into http::serve. It is boxed up and attached to each request.
  • Loading branch information
jwilm committed Nov 20, 2015
1 parent 1da0df3 commit a8d01bf
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 31 deletions.
23 changes: 18 additions & 5 deletions src/bin/racerd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ extern crate docopt;
extern crate rustc_serialize;
extern crate libracerd;

use libracerd::{Config, engine, http};
use libracerd::engine::SemanticEngine;

use std::convert::Into;

use docopt::Docopt;
Expand All @@ -11,7 +14,7 @@ const USAGE: &'static str = "
racerd - a JSON/HTTP layer on top of racer
Usage:
racerd serve --secret-file=<path> [--port=<int>] [-l] [--rustc-src-path=<path>]
racerd serve --secret-file=<path> [--port=<int>] [-l] [--rust-src-path=<path>]
racerd (-h | --help)
racerd --version
Expand All @@ -34,9 +37,9 @@ struct Args {
cmd_serve: bool
}

impl Into<libracerd::Config> for Args {
fn into(self) -> libracerd::Config {
libracerd::Config {
impl Into<Config> for Args {
fn into(self) -> Config {
Config {
port: self.flag_port as u16,
secret_file: self.flag_secret_file,
print_http_logs: self.flag_logging,
Expand All @@ -46,6 +49,7 @@ impl Into<libracerd::Config> for Args {
}

fn main() {
// Parse arguments
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.decode())
.unwrap_or_else(|e| e.exit());
Expand All @@ -56,5 +60,14 @@ fn main() {
::std::process::exit(0);
}

libracerd::http::serve(&args.into()).unwrap();
// build config object
let config: Config = args.into();

// TODO start specified semantic engine. For now, hard coded racer.
let racer = engine::Racer;
racer.initialize(&config).unwrap();

// Start serving
let server = http::serve(&config, racer).unwrap();
println!("racerd listening at {}", server.addr());
}
1 change: 0 additions & 1 deletion src/engine/racer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! SemanticEngine implementation for [the racer library](https://github.com/phildawes/racer)
//!
use std::path::Path;
use engine::{SemanticEngine, Definition, Context, CursorPosition, Completion};

use racer::core::Session;
Expand Down
13 changes: 8 additions & 5 deletions src/http/completion.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use iron::prelude::*;
use iron::status;
use iron::mime::Mime;

use http::definition;
use rustc_serialize::json;

use engine::{SemanticEngine, Racer, Completion, Context, CursorPosition, Buffer};
use engine::{SemanticEngine, Completion, Context, CursorPosition, Buffer};
use super::EngineProvider;

/// Given a location, return a list of possible completions
pub fn list(req: &mut Request) -> IronResult<Response> {
Expand All @@ -23,13 +24,15 @@ pub fn list(req: &mut Request) -> IronResult<Response> {
}
};

let racer = Racer;
match racer.list_completions(&lcr.context()) {
let mutex = req.get::<::persistent::Write<EngineProvider>>().unwrap();
let engine = mutex.lock().unwrap();
match engine.list_completions(&lcr.context()) {
// 200 OK; found the definition
Ok(Some(completions)) => {
trace!("got a match");
let res = completions.into_iter().map(|c| CompletionResponse::from(c)).collect::<Vec<_>>();
Ok(Response::with((status::Ok, json::encode(&res).unwrap())))
let content_type = "application/json".parse::<Mime>().unwrap();
Ok(Response::with((content_type, status::Ok, json::encode(&res).unwrap())))
},

// 204 No Content; Everything went ok, but the definition was not found.
Expand Down
13 changes: 8 additions & 5 deletions src/http/definition.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//! Provider for finding definitions
use iron::prelude::*;
use iron::status;
use iron::mime::Mime;

use rustc_serialize::json;

use engine::{SemanticEngine, Racer, Definition, Context, CursorPosition, Buffer};
use engine::{SemanticEngine, Definition, Context, CursorPosition, Buffer};
use super::EngineProvider;

/// Given a location, return where the identifier is defined
///
Expand Down Expand Up @@ -33,14 +35,15 @@ pub fn find(req: &mut Request) -> IronResult<Response> {
}
};

// Delegate to active semantic engine
let racer = Racer;
match racer.find_definition(&fdr.context()) {
let mutex = req.get::<::persistent::Write<EngineProvider>>().unwrap();
let engine = mutex.lock().unwrap();
match engine.find_definition(&fdr.context()) {
// 200 OK; found the definition
Ok(Some(definition)) => {
trace!("definition::find got a match");
let res = FindDefinitionResponse::from(definition);
Ok(Response::with((status::Ok, json::encode(&res).unwrap())))
let content_type = "application/json".parse::<Mime>().unwrap();
Ok(Response::with((content_type, status::Ok, json::encode(&res).unwrap())))
},

// 204 No Content; Everything went ok, but the definition was not found.
Expand Down
34 changes: 25 additions & 9 deletions src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
//!
//! ☐ File compilation

use iron::{Iron, Chain};
use iron::prelude::*;

use ::Config;

Expand All @@ -50,6 +50,10 @@ mod file;
mod completion;
mod ping;

use ::engine::SemanticEngine;

use iron::typemap::Key;

/// Errors occurring in the http module
#[derive(Debug)]
pub enum Error {
Expand All @@ -67,6 +71,17 @@ impl From<::hyper::Error> for Error {

pub type Result<T> = ::std::result::Result<T, Error>;

// -------------------------------------------------------------------------------------------------
// This is the middleware which attaches a completion engine to a given request
#[derive(Debug, Clone)]
pub struct EngineProvider;

impl Key for EngineProvider {
type Value = Box<SemanticEngine + Send>;
}

// -------------------------------------------------------------------------------------------------

/// Start the http server using the given configuration
///
/// `serve` is non-blocking.
Expand All @@ -78,18 +93,16 @@ pub type Result<T> = ::std::result::Result<T, Error>;
/// let mut cfg = Config::new();
/// cfg.port = 3000;
///
/// let mut server = ::libracerd::http::serve(&cfg).unwrap();
/// let engine = ::libracerd::engine::Racer;
///
/// let mut server = ::libracerd::http::serve(&cfg, engine).unwrap();
/// // ... later
/// server.close().unwrap();
/// ```
///
pub fn serve(config: &Config) -> Result<Server> {
use persistent::Read;
pub fn serve<E: SemanticEngine + Send + 'static>(config: &Config, engine: E) -> Result<Server> {
use persistent::{Read, Write};
use logger::Logger;
use ::engine::SemanticEngine;

let racer = ::engine::Racer;
racer.initialize(config).unwrap(); // TODO pass engine in

let mut chain = Chain::new(router!(
post "/parse_file" => file::parse,
Expand All @@ -105,6 +118,8 @@ pub fn serve(config: &Config) -> Result<Server> {
chain.link_before(log_before);
}

chain.link_before(Write::<EngineProvider>::one(Box::new(engine)));

// Body parser middlerware
chain.link_before(Read::<::bodyparser::MaxBodyLength>::one(1024 * 1024 * 10));

Expand Down Expand Up @@ -142,7 +157,8 @@ impl Server {
/// let mut config = ::libracerd::Config::new();
/// config.port = 3000;
///
/// let server = ::libracerd::http::serve(&config).unwrap();
/// let engine = ::libracerd::engine::Racer;
/// let server = ::libracerd::http::serve(&config, engine).unwrap();
///
/// assert_eq!(server.addr(), "0.0.0.0:3000");
/// ```
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
//! Documentation for the HTTP endpoints can be found in the http module header.
//!
//! This project's source code is [available on GitHub](https://github.com/jwilm/racerd).

#[deny(dead_code)]
#[deny(unused_variables)]

extern crate rustc_serialize;

#[macro_use]
Expand Down
18 changes: 12 additions & 6 deletions tests/util/http.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::ops::Deref;

use libracerd::Config;
use libracerd::engine::{Racer, SemanticEngine};

/// Smart pointer for libracerd http server.
///
Expand All @@ -11,13 +12,18 @@ pub struct TestServer {

impl TestServer {
pub fn new() -> TestServer {
let engine = Racer;
let config = Config {
port: 0,
secret_file: "/tmp/secret".to_string(),
print_http_logs: true,
rust_src_path: None,
};

engine.initialize(&config).unwrap();

TestServer {
inner: ::libracerd::http::serve(&Config {
port: 0,
secret_file: "/tmp/secret".to_string(),
print_http_logs: true,
rust_src_path: None,
}).unwrap()
inner: ::libracerd::http::serve(&config, engine).unwrap()
}
}
}
Expand Down

0 comments on commit a8d01bf

Please sign in to comment.