Return struct for response

This commit is contained in:
Gregory Schier
2023-02-15 20:26:33 -08:00
parent 2f1d3a5c60
commit 2418f737e7
5 changed files with 109 additions and 52 deletions
+24 -2
View File
@@ -9,16 +9,38 @@ fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name) format!("Hello, {}! You've been greeted from Rust!", name)
} }
#[derive(serde::Serialize)]
struct CustomResponse {
status: String,
body: String,
elapsed: u128,
elapsed2: u128,
}
#[tauri::command] #[tauri::command]
async fn send_request(url: &str) -> Result<String, String> { async fn send_request(url: &str) -> Result<CustomResponse, String> {
let start = std::time::Instant::now();
let mut url = url.to_string(); let mut url = url.to_string();
if !url.starts_with("http://") && !url.starts_with("https://") { if !url.starts_with("http://") && !url.starts_with("https://") {
url = format!("http://{}", url); url = format!("http://{}", url);
} }
let resp = reqwest::get(url).await; let resp = reqwest::get(url).await;
let elapsed = start.elapsed().as_millis();
match resp { match resp {
Ok(v) => Ok(v.text().await.unwrap()), Ok(v) => {
let status = v.status().to_string();
let body = v.text().await.unwrap();
let elapsed2 = start.elapsed().as_millis();
Ok(CustomResponse {
status,
body,
elapsed,
elapsed2,
})
}
Err(e) => Err(e.to_string()), Err(e) => Err(e.to_string()),
} }
} }
+21 -7
View File
@@ -1,23 +1,27 @@
import {useState} from "react"; import {useState} from "react";
import reactLogo from "./assets/react.svg";
import {invoke} from "@tauri-apps/api/tauri"; import {invoke} from "@tauri-apps/api/tauri";
import "./App.css"; import "./App.css";
import Editor from "./Editor"; import Editor from "./Editor";
interface Response {
body: string;
status: string;
elapsed: number;
elapsed2: number;
}
function App() { function App() {
const [responseBody, setResponseBody] = useState<string>(""); const [responseBody, setResponseBody] = useState<Response | null>(null);
const [url, setUrl] = useState(""); const [url, setUrl] = useState("");
async function sendRequest() { async function sendRequest() {
const body = await invoke("send_request", {url: url}) as string; const body = await invoke("send_request", {url: url}) as Response;
setResponseBody(body); setResponseBody(body);
} }
return ( return (
<div className="container"> <div className="container">
<h1>Welcome to Twosomnia!</h1> <h1>Welcome, Friend!</h1>
<div className="row">
<form <form
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
@@ -30,9 +34,19 @@ function App() {
placeholder="Enter a URL..." placeholder="Enter a URL..."
/> />
<button type="submit">Send</button> <button type="submit">Send</button>
<Editor value={responseBody}/>
</form> </form>
{responseBody !== null && (
<>
<div style={{paddingTop: "2rem"}}>
{responseBody?.status}
&nbsp;&bull;&nbsp;
{responseBody?.elapsed}ms
&nbsp;&bull;&nbsp;
{responseBody?.elapsed2}ms
</div> </div>
<Editor value={responseBody?.body}/>
</>
)}
</div> </div>
); );
} }
+8
View File
@@ -23,3 +23,11 @@
.cm-editor .cm-cursor { .cm-editor .cm-cursor {
border-left: 2px solid red; border-left: 2px solid red;
} }
.cm-editor .cm-selectionBackground {
background-color: rgba(180, 180, 180, 0.3);
}
.cm-editor.cm-focused .cm-selectionBackground {
background-color: rgba(180, 180, 180, 0.3);
}
+17 -13
View File
@@ -3,16 +3,11 @@ import {EditorView, minimalSetup} from "codemirror";
import {javascript} from "@codemirror/lang-javascript"; import {javascript} from "@codemirror/lang-javascript";
import {json} from "@codemirror/lang-json"; import {json} from "@codemirror/lang-json";
import {html} from "@codemirror/lang-html"; import {html} from "@codemirror/lang-html";
import {EditorState} from "@codemirror/state";
import {tags} from "@lezer/highlight" import {tags} from "@lezer/highlight"
import {HighlightStyle, syntaxHighlighting} from "@codemirror/language" import {HighlightStyle, syntaxHighlighting} from "@codemirror/language"
export default function useCodeMirror({value}: { value: string }) { const myHighlightStyle = HighlightStyle.define([
const [cm, setCm] = useState<EditorView | null>(null);
const ref = useRef(null);
useEffect(() => {
if (ref.current === null) return;
const myHighlightStyle = HighlightStyle.define([
{ {
tag: [ tag: [
tags.documentMeta, tags.documentMeta,
@@ -29,16 +24,24 @@ export default function useCodeMirror({value}: { value: string }) {
{tag: tags.attributeValue, color: "#ff964b"}, {tag: tags.attributeValue, color: "#ff964b"},
{tag: tags.keyword, color: "#fc6"}, {tag: tags.keyword, color: "#fc6"},
{tag: tags.comment, color: "#f5d", fontStyle: "italic"} {tag: tags.comment, color: "#f5d", fontStyle: "italic"}
]) ]);
const view = new EditorView({ const extensions = [
extensions: [
minimalSetup, minimalSetup,
syntaxHighlighting(myHighlightStyle), syntaxHighlighting(myHighlightStyle),
html(), html(),
javascript(), javascript(),
json(), json(),
], ];
export default function useCodeMirror({value}: { value: string }) {
const [cm, setCm] = useState<EditorView | null>(null);
const ref = useRef(null);
useEffect(() => {
if (ref.current === null) return;
const view = new EditorView({
extensions,
parent: ref.current parent: ref.current
}); });
@@ -49,8 +52,9 @@ export default function useCodeMirror({value}: { value: string }) {
useEffect(() => { useEffect(() => {
if (cm === null) return; if (cm === null) return;
let transaction = cm.state.update({changes: {from: 0, to: cm.state.doc.length, insert: value}})
cm.dispatch(transaction) const newState = EditorState.create({doc: value, extensions});
cm.setState(newState);
}, [cm, value]); }, [cm, value]);
return {ref, cm}; return {ref, cm};
+10 -1
View File
@@ -14,6 +14,14 @@
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
} }
:not(input):not(textarea),
:not(input):not(textarea)::after,
:not(input):not(textarea)::before {
-webkit-user-select: none;
user-select: none;
cursor: default;
}
div, form, p { div, form, p {
width: 100%; width: 100%;
} }
@@ -25,7 +33,8 @@ div, form, p {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
width: 700px; width: 80vw;
max-width: 800px;
} }
.logo { .logo {