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

View File

@@ -9,16 +9,38 @@ fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
#[derive(serde::Serialize)]
struct CustomResponse {
status: String,
body: String,
elapsed: u128,
elapsed2: u128,
}
#[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();
if !url.starts_with("http://") && !url.starts_with("https://") {
url = format!("http://{}", url);
}
let resp = reqwest::get(url).await;
let elapsed = start.elapsed().as_millis();
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()),
}
}

View File

@@ -1,38 +1,52 @@
import {useState} from "react";
import reactLogo from "./assets/react.svg";
import {invoke} from "@tauri-apps/api/tauri";
import "./App.css";
import Editor from "./Editor";
interface Response {
body: string;
status: string;
elapsed: number;
elapsed2: number;
}
function App() {
const [responseBody, setResponseBody] = useState<string>("");
const [responseBody, setResponseBody] = useState<Response | null>(null);
const [url, setUrl] = useState("");
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);
}
return (
<div className="container">
<h1>Welcome to Twosomnia!</h1>
<div className="row">
<form
onSubmit={(e) => {
e.preventDefault();
sendRequest();
}}
>
<input
id="greet-input"
onChange={(e) => setUrl(e.currentTarget.value)}
placeholder="Enter a URL..."
/>
<button type="submit">Send</button>
<Editor value={responseBody}/>
</form>
</div>
<h1>Welcome, Friend!</h1>
<form
onSubmit={(e) => {
e.preventDefault();
sendRequest();
}}
>
<input
id="greet-input"
onChange={(e) => setUrl(e.currentTarget.value)}
placeholder="Enter a URL..."
/>
<button type="submit">Send</button>
</form>
{responseBody !== null && (
<>
<div style={{paddingTop: "2rem"}}>
{responseBody?.status}
&nbsp;&bull;&nbsp;
{responseBody?.elapsed}ms
&nbsp;&bull;&nbsp;
{responseBody?.elapsed2}ms
</div>
<Editor value={responseBody?.body}/>
</>
)}
</div>
);
}

View File

@@ -23,3 +23,11 @@
.cm-editor .cm-cursor {
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);
}

View File

@@ -3,42 +3,45 @@ import {EditorView, minimalSetup} from "codemirror";
import {javascript} from "@codemirror/lang-javascript";
import {json} from "@codemirror/lang-json";
import {html} from "@codemirror/lang-html";
import {EditorState} from "@codemirror/state";
import {tags} from "@lezer/highlight"
import {HighlightStyle, syntaxHighlighting} from "@codemirror/language"
const myHighlightStyle = HighlightStyle.define([
{
tag: [
tags.documentMeta,
tags.blockComment,
tags.lineComment,
tags.docComment,
tags.comment,
],
color: "#757b93"
},
{tag: tags.name, color: "#4b92ff"},
{tag: tags.variableName, color: "#4bff4e"},
{tag: tags.attributeName, color: "#b06fff"},
{tag: tags.attributeValue, color: "#ff964b"},
{tag: tags.keyword, color: "#fc6"},
{tag: tags.comment, color: "#f5d", fontStyle: "italic"}
]);
const extensions = [
minimalSetup,
syntaxHighlighting(myHighlightStyle),
html(),
javascript(),
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 myHighlightStyle = HighlightStyle.define([
{
tag: [
tags.documentMeta,
tags.blockComment,
tags.lineComment,
tags.docComment,
tags.comment,
],
color: "#757b93"
},
{tag: tags.name, color: "#4b92ff"},
{tag: tags.variableName, color: "#4bff4e"},
{tag: tags.attributeName, color: "#b06fff"},
{tag: tags.attributeValue, color: "#ff964b"},
{tag: tags.keyword, color: "#fc6"},
{tag: tags.comment, color: "#f5d", fontStyle: "italic"}
])
const view = new EditorView({
extensions: [
minimalSetup,
syntaxHighlighting(myHighlightStyle),
html(),
javascript(),
json(),
],
extensions,
parent: ref.current
});
@@ -49,8 +52,9 @@ export default function useCodeMirror({value}: { value: string }) {
useEffect(() => {
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]);
return {ref, cm};

View File

@@ -14,6 +14,14 @@
-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 {
width: 100%;
}
@@ -25,7 +33,8 @@ div, form, p {
flex-direction: column;
justify-content: center;
text-align: center;
width: 700px;
width: 80vw;
max-width: 800px;
}
.logo {