diff --git a/src/main/java/com/github/jlangch/venice/impl/functions/IOFunctions.java b/src/main/java/com/github/jlangch/venice/impl/functions/IOFunctions.java index bde347635..2881adf6a 100644 --- a/src/main/java/com/github/jlangch/venice/impl/functions/IOFunctions.java +++ b/src/main/java/com/github/jlangch/venice/impl/functions/IOFunctions.java @@ -60,6 +60,7 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; import com.github.jlangch.venice.SecurityException; import com.github.jlangch.venice.VncException; @@ -93,6 +94,8 @@ import com.github.jlangch.venice.javainterop.IInterceptor; import com.github.jlangch.venice.javainterop.ILoadPaths; +import net.lingala.zip4j.util.FileUtils; + public class IOFunctions { @@ -424,26 +427,40 @@ public VncVal apply(final VncList args) { VncFunction .meta() .arglists( - "(io/file-ext? f ext)") + "(io/file-ext? f ext & exts)") .doc( "Returns true if the file f hast the extension ext. " + "f must be a file or a string (file path).") .examples( "(io/file-ext? \"/tmp/test/x.txt\" \"txt\")", - "(io/file-ext? (io/file \"/tmp/test/x.txt\") \".txt\")") + "(io/file-ext? (io/file \"/tmp/test/x.txt\") \".txt\")", + "(io/file-ext? \"/tmp/test/x.docx\" \"doc\" \"docx\")") .seeAlso("io/file-ext") .build() ) { @Override public VncVal apply(final VncList args) { - ArityExceptions.assertArity(this, args, 2); + ArityExceptions.assertMinArity(this, args, 2); final File f = convertToFile( args.first(), "Function 'io/file-ext?' does not allow %s as f"); - final String ext = Coerce.toVncString(args.second()).getValue(); - return VncBoolean.of(f.getName().endsWith(ext.startsWith(".") ? ext : "." + ext)); + if (args.size() == 2) { + final String ext = Coerce.toVncString(args.second()).getValue(); + return VncBoolean.of(f.getName().endsWith(ext.startsWith(".") ? ext : "." + ext)); + } + else { + final Set exts = args.slice(1) + .stream() + .map(v -> Coerce.toVncString(args.second()).getValue()) + .map(s -> s.startsWith(".") ? s.substring(1) : s) + .collect(Collectors.toSet()); + + final String fileExt = FileUtils.getFileExtension(f); + + return VncBoolean.of(exts.contains(fileExt)); + } } private static final long serialVersionUID = -1848883965231344442L; diff --git a/src/test/java/com/github/jlangch/venice/impl/functions/IOFunctionsTest.java b/src/test/java/com/github/jlangch/venice/impl/functions/IOFunctionsTest.java index 040b6e099..c7e62608e 100644 --- a/src/test/java/com/github/jlangch/venice/impl/functions/IOFunctionsTest.java +++ b/src/test/java/com/github/jlangch/venice/impl/functions/IOFunctionsTest.java @@ -173,7 +173,20 @@ public void test_io_file_ext_Q() { assertTrue((Boolean)venice.eval("(io/file-ext? (io/file \"/tmp/some.png\") \"png\")")); assertTrue((Boolean)venice.eval("(io/file-ext? (io/file \"/tmp/some.png\") \".png\")")); - } + + + assertTrue((Boolean)venice.eval("(io/file-ext? \"some.png\" \"png\" \"jpg\" \"gif\")")); + assertTrue((Boolean)venice.eval("(io/file-ext? \"some.png\" \".png\" \".jpg\" \".gif\")")); + + assertTrue((Boolean)venice.eval("(io/file-ext? \"/tmp/some.png\" \"png\" \"jpg\" \"gif\")")); + assertTrue((Boolean)venice.eval("(io/file-ext? \"/tmp/some.png\" \".png\" \".jpg\" \".gif\")")); + + assertTrue((Boolean)venice.eval("(io/file-ext? (io/file \"some.png\") \"png\" \"jpg\" \"gif\")")); + assertTrue((Boolean)venice.eval("(io/file-ext? (io/file \"some.png\") \".png\" \".jpg\" \".gif\")")); + + assertTrue((Boolean)venice.eval("(io/file-ext? (io/file \"/tmp/some.png\") \"png\" \"jpg\" \"gif\")")); + assertTrue((Boolean)venice.eval("(io/file-ext? (io/file \"/tmp/some.png\") \".png\" \".jpg\" \".gif\")")); + } @Test public void test_io_file_ext() {