From aac22ed261e5c4b753a6b15d863ec2cc3d186a5c Mon Sep 17 00:00:00 2001
From: Alejandro Perea <alexpro820@gmail.com>
Date: Mon, 7 Mar 2022 12:32:37 +0100
Subject: [PATCH] Better specification for `Image::source` + example (#186)

---
 assets/folder/tiled_relative_paths.tmx | 27 ++++++++++++++
 src/image.rs                           | 51 +++++++++++++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 assets/folder/tiled_relative_paths.tmx

diff --git a/assets/folder/tiled_relative_paths.tmx b/assets/folder/tiled_relative_paths.tmx
new file mode 100644
index 0000000..c330a5c
--- /dev/null
+++ b/assets/folder/tiled_relative_paths.tmx
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.8" tiledversion="1.8.2" orientation="orthogonal" renderorder="right-down" width="16" height="16" tilewidth="32" tileheight="32" infinite="0" nextlayerid="3" nextobjectid="1">
+ <tileset firstgid="1" source="../tilesheet.tsx"/>
+ <layer id="1" name="Tile Layer 1" width="16" height="16">
+  <data encoding="csv">
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21
+</data>
+ </layer>
+ <imagelayer id="2" name="image">
+  <image source="../tilesheet.png" width="448" height="192"/>
+ </imagelayer>
+</map>
diff --git a/src/image.rs b/src/image.rs
index 9220a93..b0df041 100644
--- a/src/image.rs
+++ b/src/image.rs
@@ -7,14 +7,63 @@ use crate::{error::TiledError, properties::Color, util::*};
 /// A reference to an image stored somewhere within the filesystem.
 #[derive(Debug, PartialEq, Eq, Clone)]
 pub struct Image {
-    /// The filepath of the image.
+    /// The **uncanonicalized** filepath of the image, starting from the path given to load the file
+    /// this image is in. See the example for more details.
     ///
     /// ## Note
     /// The crate does not currently support embedded images (Even though Tiled
     /// does not allow creating maps with embedded image data, the TMX format does; [source])
     ///
+    /// Currently, the crate is not prepared to handle anything but OS paths. Using VFS is a hard
+    /// task that involves a lot of messy path manipulation. [Tracking issue]
+    ///
     /// [source]: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#image
+    /// [Tracking issue]: https://github.com/mapeditor/rs-tiled/issues/37
+    ///
+    /// ## Example
+    /// ```
+    /// use std::path::Path;
+    /// use std::fs::File;
+    /// use tiled::*;
+    ///
+    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+    /// let map = Map::parse_file(
+    ///     "assets/folder/tiled_relative_paths.tmx",
+    ///     &mut FilesystemResourceCache::new(),
+    /// )?;
+    ///
+    /// let image_layer = match map
+    ///     .layers()
+    ///     .find(|layer| layer.name() == "image")
+    ///     .unwrap()
+    ///     .layer_type()
+    /// {
+    ///     LayerType::ImageLayer(layer) => layer,
+    ///     _ => panic!(),
+    /// };
+    ///
+    /// // Image layer has an image with the source attribute set to "../tilesheet.png"
+    /// // Given the information we gave to the `parse_file` function, the image source should be
+    /// // "assets/folder/../tilesheet.png". The filepath is not canonicalized.
+    /// let image_source = &image_layer.image().unwrap().source;
+    ///
+    /// assert_eq!(
+    ///     image_source,
+    ///     Path::new("assets/folder/../tilesheet.png")
+    /// );
+    ///
+    /// // If you are using the OS's filesystem, figuring out the real path of the image is as easy
+    /// // as canonicalizing the path. If you are using some sort of VFS, this task is much harder
+    /// // since std::path is meant to be used with the OS. This will be fixed in the future!
+    /// let image_source = image_source.canonicalize()?;
+    /// assert!(File::open(image_source).is_ok());
+    /// # Ok(())
+    /// # }
+    /// ```
+    /// Check the assets/tiled_relative_paths.tmx file at the crate root to see the structure of the
+    /// file this example is referring to.
     // TODO: Embedded images
+    // TODO: Figure out how to serve crate users paths in a better way
     pub source: PathBuf,
     /// The width in pixels of the image.
     pub width: i32,
-- 
GitLab