summaryrefslogtreecommitdiff
path: root/src/library/elements.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-07-30 18:04:08 +0200
committerLaurenz <laurmaedje@gmail.com>2021-07-30 18:49:19 +0200
commit1ee1d078e2480ddd08d40915bc7a74a8352acff0 (patch)
tree1e7ff367278a19fead3e404cf06d65bfb80a6cd9 /src/library/elements.rs
parent42a27b48df427edf8dbb624c51551a90ecf2e7ea (diff)
Fatal errors
- Makes errors fatal, so that a phase is only reached when all previous phases were error-free - Parsing still recovers and can produce multiple errors - Evaluation fails fast and can thus produce only a single error (except for parse errors due to an import) - The single error that could occur during execution is removed for now - Removes Value::Error variant
Diffstat (limited to 'src/library/elements.rs')
-rw-r--r--src/library/elements.rs91
1 files changed, 48 insertions, 43 deletions
diff --git a/src/library/elements.rs b/src/library/elements.rs
index afd7444e..3d318d36 100644
--- a/src/library/elements.rs
+++ b/src/library/elements.rs
@@ -8,46 +8,44 @@ use crate::layout::{
};
/// `image`: An image.
-pub fn image(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let path = args.expect::<Spanned<EcoString>>(ctx, "path to image file");
- let width = args.named(ctx, "width");
- let height = args.named(ctx, "height");
-
- let mut node = None;
- if let Some(path) = &path {
- if let Some(file) = ctx.resolve(&path.v, path.span) {
- if let Some(id) = ctx.images.load(file) {
- node = Some(ImageNode { id, width, height });
- } else {
- ctx.diag(error!(path.span, "failed to load image"));
- }
- }
- }
-
- Value::template(move |ctx| {
- if let Some(node) = node {
- ctx.push_into_par(node);
- }
- })
+pub fn image(ctx: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+ let path = args.expect::<Spanned<EcoString>>("path to image file")?;
+ let width = args.named("width")?;
+ let height = args.named("height")?;
+
+ let file = ctx.resolve(&path.v, path.span)?;
+ let node = match ctx.images.load(file) {
+ Some(id) => ImageNode { id, width, height },
+ None => bail!(args.file, path.span, "failed to load image"),
+ };
+
+ Ok(Value::template(move |ctx| ctx.push_into_par(node)))
}
/// `rect`: A rectangle with optional content.
-pub fn rect(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let width = args.named(ctx, "width");
- let height = args.named(ctx, "height");
- let fill = args.named(ctx, "fill");
+pub fn rect(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+ let width = args.named("width")?;
+ let height = args.named("height")?;
+ let fill = args.named("fill")?;
let body = args.eat().unwrap_or_default();
- rect_impl(width, height, None, fill, body)
+ Ok(rect_impl(width, height, None, fill, body))
}
/// `square`: A square with optional content.
-pub fn square(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let length = args.named::<Length>(ctx, "length").map(Linear::from);
- let width = length.or_else(|| args.named(ctx, "width"));
- let height = width.is_none().then(|| args.named(ctx, "height")).flatten();
- let fill = args.named(ctx, "fill");
+pub fn square(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+ let length = args.named::<Length>("length")?.map(Linear::from);
+ let width = match length {
+ Some(length) => Some(length),
+ None => args.named("width")?,
+ };
+ let height = match width {
+ Some(_) => None,
+ None => args.named("height")?,
+ };
+ let aspect = Some(N64::from(1.0));
+ let fill = args.named("fill")?;
let body = args.eat().unwrap_or_default();
- rect_impl(width, height, Some(N64::from(1.0)), fill, body)
+ Ok(rect_impl(width, height, aspect, fill, body))
}
fn rect_impl(
@@ -76,22 +74,29 @@ fn rect_impl(
}
/// `ellipse`: An ellipse with optional content.
-pub fn ellipse(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let width = args.named(ctx, "width");
- let height = args.named(ctx, "height");
- let fill = args.named(ctx, "fill");
+pub fn ellipse(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+ let width = args.named("width")?;
+ let height = args.named("height")?;
+ let fill = args.named("fill")?;
let body = args.eat().unwrap_or_default();
- ellipse_impl(width, height, None, fill, body)
+ Ok(ellipse_impl(width, height, None, fill, body))
}
/// `circle`: A circle with optional content.
-pub fn circle(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
- let diameter = args.named::<Length>(ctx, "radius").map(|r| 2.0 * Linear::from(r));
- let width = diameter.or_else(|| args.named(ctx, "width"));
- let height = width.is_none().then(|| args.named(ctx, "height")).flatten();
- let fill = args.named(ctx, "fill");
+pub fn circle(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+ let diameter = args.named("radius")?.map(|r: Length| 2.0 * Linear::from(r));
+ let width = match diameter {
+ None => args.named("width")?,
+ diameter => diameter,
+ };
+ let height = match width {
+ None => args.named("height")?,
+ width => width,
+ };
+ let aspect = Some(N64::from(1.0));
+ let fill = args.named("fill")?;
let body = args.eat().unwrap_or_default();
- ellipse_impl(width, height, Some(N64::from(1.0)), fill, body)
+ Ok(ellipse_impl(width, height, aspect, fill, body))
}
fn ellipse_impl(