Implement /api/v1/pastes

This commit is contained in:
Konrad Borowski 2021-10-19 12:28:27 +02:00
parent f890f27265
commit 4ccf9b6e23
5 changed files with 108 additions and 1 deletions

53
Cargo.lock generated
View File

@ -35,6 +35,18 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "anyhow"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "async-stream"
version = "0.3.2"
@ -917,6 +929,19 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if 1.0.0",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.104"
@ -1162,6 +1187,17 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"lexical-core",
"memchr",
"version_check",
]
[[package]]
name = "normpath"
version = "0.3.1"
@ -1325,6 +1361,7 @@ dependencies = [
"rocket_sync_db_pools",
"serde",
"serde_json",
"time-parse",
]
[[package]]
@ -2141,6 +2178,12 @@ dependencies = [
"loom",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "stdweb"
version = "0.4.20"
@ -2332,6 +2375,16 @@ dependencies = [
"syn",
]
[[package]]
name = "time-parse"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1160cce3eff1e83f47add604ad3ad0b0609e2f76deb6143f699d40d55a2a83a"
dependencies = [
"anyhow",
"nom",
]
[[package]]
name = "tinyvec"
version = "1.5.0"

View File

@ -22,6 +22,7 @@ rocket_dyn_templates = { version = "0.1.0-rc.1", features = ["tera"] }
rocket_sync_db_pools = { version = "0.1.0-rc.1", features = ["diesel_postgres_pool"] }
serde = { version = "1.0.126", features = ["derive"] }
serde_json = "1.0.64"
time-parse = "0.2.0"
[features]
database_tests = []

View File

@ -24,7 +24,9 @@ mod models;
mod routes;
mod schema;
use crate::routes::{api_language, display_paste, index, insert_paste, raw_paste, run};
use crate::routes::{
api_insert_paste, api_language, display_paste, index, insert_paste, raw_paste, run,
};
use diesel::prelude::*;
use rocket::fairing::AdHoc;
use rocket::fs::{relative, FileServer};
@ -67,6 +69,7 @@ async fn rocket() -> _ {
"/",
routes![
api_language,
api_insert_paste,
run,
index,
insert_paste,

View File

@ -0,0 +1,48 @@
use crate::models::paste::{self, ExtraPasteParameters, InsertionError};
use crate::Db;
use chrono::Duration;
use chrono::Utc;
use rocket::form::{self, Form, FromFormField, Strict, ValueField};
use std::error::Error;
#[derive(FromForm)]
pub struct PasteForm {
#[field(default = Expiration(None))]
expiration: Expiration,
#[field(default = "plaintext")]
language: String,
code: String,
}
struct Expiration(Option<Duration>);
impl<'r> FromFormField<'r> for Expiration {
fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> {
let duration = time_parse::duration::parse_nom(field.value).map_err(Box::from)?;
let duration =
Duration::from_std(duration).map_err(|x| -> Box<dyn Error + Send> { Box::new(x) })?;
Ok(Self(Some(duration)))
}
}
#[post("/api/v1/pastes", data = "<form>")]
pub async fn api_insert_paste(
db: Db,
form: Form<Strict<PasteForm>>,
) -> Result<String, InsertionError> {
db.run(move |conn| {
paste::insert(
conn,
form.expiration.0.map(|expiration| Utc::now() + expiration),
&form.language,
&form.code,
ExtraPasteParameters {
stdin: "",
stdout: None,
stderr: None,
exit_code: None,
},
)
})
.await
}

View File

@ -14,6 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
mod api_insert_paste_route;
mod api_language_route;
mod display_paste_route;
mod index_route;
@ -21,6 +22,7 @@ mod insert_paste_route;
mod raw_paste_route;
mod run_route;
pub use api_insert_paste_route::*;
pub use api_language_route::*;
pub use display_paste_route::*;
pub use index_route::*;