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

Commit

Permalink
dev: decouple hyper
Browse files Browse the repository at this point in the history
  • Loading branch information
Myriad-Dreamin committed Dec 19, 2023
1 parent bf71cc4 commit c858516
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 69 deletions.
30 changes: 15 additions & 15 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ const ENV_PATH_SEP: char = if cfg!(windows) { ';' } else { ':' };

#[derive(Debug, Clone, Parser)]
pub struct PreviewArgs {
/// Preview mode
#[clap(long = "preview-mode", default_value = "document", value_name = "MODE")]
pub preview_mode: PreviewMode,

/// Data plane server will bind to this address
#[clap(
long = "data-plane-host",
Expand All @@ -41,6 +37,21 @@ pub struct PreviewArgs {
)]
pub control_plane_host: String,

/// Only render visible part of the document. This can improve performance but still being experimental.
#[clap(long = "partial-rendering")]
pub enable_partial_rendering: bool,
}

#[derive(Debug, Clone, Parser)]
#[clap(name = "typst-preview", author, version, about, long_version(LONG_VERSION.as_str()))]
pub struct CliArguments {
#[clap(flatten)]
pub preview: PreviewArgs,

/// Preview mode
#[clap(long = "preview-mode", default_value = "document", value_name = "MODE")]
pub preview_mode: PreviewMode,

/// Host for the preview server
#[clap(
long = "host",
Expand All @@ -54,17 +65,6 @@ pub struct PreviewArgs {
#[clap(long = "no-open")]
pub dont_open_in_browser: bool,

/// Only render visible part of the document. This can improve performance but still being experimental.
#[clap(long = "partial-rendering")]
pub enable_partial_rendering: bool,
}

#[derive(Debug, Clone, Parser)]
#[clap(name = "typst-preview", author, version, about, long_version(LONG_VERSION.as_str()))]
pub struct CliArguments {
#[clap(flatten)]
pub preview: PreviewArgs,

/// Add additional directories to search for fonts
#[clap(long = "font-path", value_name = "DIR", action = ArgAction::Append, env = "TYPST_FONT_PATHS", value_delimiter = ENV_PATH_SEP)]
pub font_paths: Vec<PathBuf>,
Expand Down
54 changes: 2 additions & 52 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ mod outline;
use std::{collections::HashMap, path::PathBuf, sync::Arc};

use futures::SinkExt;
use hyper::{
service::{make_service_fn, service_fn},
Error,
};
use log::{error, info};
use log::info;
use serde::Deserialize;
use tokio::net::{TcpListener, TcpStream};
use tokio_tungstenite::tungstenite::Message;
Expand Down Expand Up @@ -71,20 +67,14 @@ pub struct MemoryFilesShort {
const HTML: &str = include_str!("../addons/vscode/out/frontend/index.html");

pub struct Previewer {
frontend_html: ImmutStr,
frontend_html_factory: Box<dyn Fn(PreviewMode) -> ImmutStr>,
data_plane_handle: tokio::task::JoinHandle<()>,
control_plane_handle: tokio::task::JoinHandle<()>,
}

impl Previewer {
/// Get the HTML for the frontend (with set preview mode)
pub fn frontend_html(&self) -> ImmutStr {
self.frontend_html.clone()
}

/// Get the HTML for the frontend by a given preview mode
pub fn frontend_html_in_mode(&self, mode: PreviewMode) -> ImmutStr {
pub fn frontend_html(&self, mode: PreviewMode) -> ImmutStr {
(self.frontend_html_factory)(mode)
}

Expand Down Expand Up @@ -230,48 +220,8 @@ pub async fn preview(arguments: PreviewArgs, compiler_driver: CompileDriver) ->
)
.into()
});
let mode = arguments.preview_mode;
let frontend_html = frontend_html_factory(mode);
let make_service = make_service_fn(|_| {
let html = frontend_html.clone();
async move {
Ok::<_, hyper::http::Error>(service_fn(move |req| {
// todo: clone may not be necessary
let html = html.as_ref().to_owned();
async move {
if req.uri().path() == "/" {
log::info!("Serve frontend: {:?}", mode);
Ok::<_, Error>(hyper::Response::new(hyper::Body::from(html)))
} else {
// jump to /
let mut res = hyper::Response::new(hyper::Body::empty());
*res.status_mut() = hyper::StatusCode::FOUND;
res.headers_mut().insert(
hyper::header::LOCATION,
hyper::header::HeaderValue::from_static("/"),
);
Ok(res)
}
}
}))
}
});
let static_file_addr = arguments.static_file_host;
if !static_file_addr.is_empty() {
let server = hyper::Server::bind(&static_file_addr.parse().unwrap()).serve(make_service);
if !arguments.dont_open_in_browser {
if let Err(e) = open::that_detached(format!("http://{}", server.local_addr())) {
error!("failed to open browser: {}", e);
};
}
info!("Static file server listening on: {}", server.local_addr());
if let Err(e) = server.await {
error!("Static file server error: {}", e);
}
}

Previewer {
frontend_html,
frontend_html_factory,
data_plane_handle,
control_plane_handle,
Expand Down
61 changes: 59 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,52 @@ use typst_ts_compiler::service::CompileDriver;
use typst_ts_compiler::TypstSystemWorld;
use typst_ts_core::config::CompileOpts;

use typst_preview::{preview, CliArguments};
use hyper::{
service::{make_service_fn, service_fn},
Error,
};

use typst_preview::{preview, CliArguments, PreviewMode, Previewer};

pub async fn make_static_host(
previewer: &Previewer,
static_file_addr: String,
mode: PreviewMode,
) -> SocketAddr {
let frontend_html = previewer.frontend_html(mode);
let make_service = make_service_fn(|_| {
let html = frontend_html.clone();
async move {
Ok::<_, hyper::http::Error>(service_fn(move |req| {
// todo: clone may not be necessary
let html = html.as_ref().to_owned();
async move {
if req.uri().path() == "/" {
log::info!("Serve frontend: {:?}", mode);
Ok::<_, Error>(hyper::Response::new(hyper::Body::from(html)))
} else {
// jump to /
let mut res = hyper::Response::new(hyper::Body::empty());
*res.status_mut() = hyper::StatusCode::FOUND;
res.headers_mut().insert(
hyper::header::LOCATION,
hyper::header::HeaderValue::from_static("/"),
);
Ok(res)
}
}
}))
}
});
let server = hyper::Server::bind(&static_file_addr.parse().unwrap()).serve(make_service);

let addr = server.local_addr();
if let Err(e) = server.await {
error!("Static file server error: {}", e);
}

addr
}

/// Entry point.
#[tokio::main]
Expand Down Expand Up @@ -62,10 +107,22 @@ async fn main() {

let previewer = preview(arguments.preview, compiler_driver).await;

let static_file_addr = arguments.static_file_host;
let mode = arguments.preview_mode;
if !static_file_addr.is_empty() {
let addr = make_static_host(&previewer, static_file_addr, mode).await;
info!("Static file server listening on: {}", addr);
if !arguments.dont_open_in_browser {
if let Err(e) = open::that_detached(format!("http://{}", addr)) {
error!("failed to open browser: {}", e);
};
}
}

previewer.join().await;
}

use std::borrow::Cow;
use std::{borrow::Cow, net::SocketAddr};

pub static EMBEDDED_FONT: &[Cow<'_, [u8]>] = &[
// Embed default fonts.
Expand Down

0 comments on commit c858516

Please sign in to comment.