Sample Page

This is a sample page composed in AsciiDoc. Jekyll converts it to HTML using Asciidoctor.

Note
An admonition draws the reader’s attention to auxiliary information.

Here are the other built-in admonition types:

Important
Don’t forget the children!
Tip
Look for the warp zone under the bridge.
Caution
Slippery when wet.
Warning
The software you’re about to use is untested.
Important
Sign off before stepping away from your computer.
pub fn process_image(
    image: &FieldData<NamedTempFile>,
    save_path: String,
) -> Result<ImageDetails, String>
{
    let Some(stated_content_type) = image.metadata.content_type.clone()
    else
    {
        return Err("No content type was provided for file".to_string());
    };

    let given_file_name = &image.metadata.file_name;

    let with_extension = match given_file_name
    {
        Some(f) => match Path::new(f).extension()
        {
            Some(e) =>
            {
                let mime =
                    mime_guess::get_mime_extensions_str(&stated_content_type);
                match mime
                {
                    Some(m) =>
                    {
                        tracing::debug!("{:?}", m);
                        let e_str = e.to_str();
                        match e_str
                        {
                            Some(valid_ext) =>
                            {
                                let string_mimes = m
                                    .iter()
                                    .map(|ext| ext.to_string())
                                    .collect::<Vec<String>>();
                                if string_mimes
                                    .contains(&valid_ext.to_lowercase())
                                {
                                    Ok((f.to_string(), valid_ext))
                                }
                                else
                                {
                                    tracing::error!(
                                        "File extension does not match \
                                         content type"
                                    );
                                    Err(format!(
                                        "File {}: extension does not match \
                                         content type",
                                        f
                                    )
                                    .to_string())
                                }
                            }
                            None =>
                            {
                                tracing::error!(
                                    "Could not decode file extension as UTF-8"
                                );
                                Err(format!(
                                    "File {}: extension could not be decoded",
                                    f
                                )
                                .to_string())
                            }
                        }
                    }
                    None =>
                    {
                        tracing::error!(
                            "Could not determine extension by content type"
                        );
                        Err(format!(
                            "File {}: Proper extension could not be resolved",
                            f
                        )
                        .to_string())
                    }
                }
            }
            None =>
            {
                tracing::error!("File extension is required");
                Err(format!("File {}: No file extension provided", f)
                    .to_string())
            }
        },
        None =>
        {
            tracing::error!("Original file name is missing");
            Err("File ?: Original file name is missing".to_string())
        }
    };

    let (orig_name, file_extension) = match with_extension
    {
        Ok(ext) => ext,
        Err(e) => return Err(e),
    };

    // Determine if the file's magic number matches with the stated content type
    let (mime_info, mime_type) =
        match infer::get_from_path(image.contents.path())
        {
            Ok(Some(info)) =>
            {
                let mtype = info.mime_type();
                if mtype != stated_content_type.to_string().to_lowercase()
                {
                    tracing::error!(
                        "Determined file type does not match stated file type"
                    );
                    return Err("Mismatch between stated and actual file \
                                type"
                        .to_string());
                }
                else
                {
                    (info.matcher_type(), mtype.to_string())
                }
            }
            Ok(None) =>
            {
                tracing::error!("Unknown file rusttype");
                return Err("Provided file type is not supported".to_string());
            }
            Err(e) =>
            {
                tracing::error!("Error reading file type from file: {:?}", e);
                return Err(format!("File type error: {}", e).to_string());
            }
        };

    // Give the file a unique enough name
    let img_filename = Uuid::new_v4().to_string() + "." + file_extension;
    let img_path = Path::new(&save_path).join(&img_filename);
    tracing::info!("Saving file to {}", img_path.display());

    match fs::copy(image.contents.path(), &img_path)
    {
        Ok(_) =>
        {
            tracing::info!("File saved");

            // Delete temp file
            cleanup_file_path(image.contents.path());
        }
        Err(e) =>
        {
            tracing::error!("Could not save file: {:?}", e);
            return Err(
                format!("File {}: Save file error", orig_name).to_string()
            );
        }
    }

    let Ok(metadata) = fs::metadata(Path::new(&img_path))
    else
    {
        tracing::error!("Could not fetch file metadata");
        cleanup_file_path(&img_path);

        return Err(format!(
            "File {}: metadata error in determining size",
            orig_name
        )
        .to_string());
    };

    // Hashing this way will not run the whole file into memory
    let mut hasher = Sha256::new();
    let hashing_file = fs::File::open(&img_path);
    let file_hash = match hashing_file
    {
        Err(e) =>
        {
            tracing::error!("Could not open file for hashing: {:?}", e);
            return Err(format!(
                "File {}: Error opening file for hashing",
                orig_name
            )
            .to_string());
        }
        Ok(mut hf) =>
        {
            let Ok(_) = io::copy(&mut hf, &mut hasher)
            else
            {
                tracing::error!("Could not copy file for hashing");
                return Err(format!("File {}: Error hashing file", orig_name)
                    .to_string());
            };
            let hash = hasher.finalize();
            Base64::encode_string(&hash)
        }
    };

    match mime_info
    {
        infer::MatcherType::Image => match process_image_thumbnail(
            &img_path,
            save_path,
            img_filename.clone(),
            250,
            250,
        )
        {
            Ok(thumb_result) => Ok(ImageDetails {
                file_path: img_path,
                thumb_path: thumb_result.thumb_path,
                rel_file_path: img_filename,
                rel_thumb_path: thumb_result.thumb_filename,
                orig_name,
                extension: mime_type,
                file_w: thumb_result.image_width,
                file_h: thumb_result.image_height,
                file_size: metadata.len(),
                hash: file_hash,
            }),
            Err(e) => Err(e),
        },
        infer::MatcherType::Video =>
        {
            Err("Videos are not currenty supported".to_string())
        }
        infer::MatcherType::Audio => Ok(ImageDetails {
            file_path: img_path,
            thumb_path: "".into(),
            rel_file_path: img_filename,
            rel_thumb_path: "".to_string(),
            orig_name,
            extension: mime_type,
            file_w: 0u32,
            file_h: 0u32,
            file_size: metadata.len(),
            hash: file_hash,
        }),
        _ => Err("Unsupported MIME category supplied".to_string()),
    }
}

And there you have it!