Skip to content

Commit

Permalink
content type renamed to media type to be more in line with MIME spec
Browse files Browse the repository at this point in the history
  • Loading branch information
morisil committed Dec 24, 2024
1 parent ac6e7ab commit dd55787
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ package com.xemantic.ai.file.magic

import kotlinx.io.files.Path

/**
* A subset of MIME types and associated type detectors.
*/
@OptIn(ExperimentalUnsignedTypes::class)
public enum class ContentType(
public enum class MediaType(
public val mime: String,
private val detect: (ByteArray) -> Boolean
) {
Expand All @@ -36,7 +39,7 @@ public enum class ContentType(

GIF(
mime = "image/gif",
detect = { it.startsWith("GIF87", "GIF89") }
detect = { it.startsWith("GIF87") || it.startsWith("GIF89") }
),

WEBP(
Expand All @@ -53,7 +56,7 @@ public enum class ContentType(

public fun detect(
bytes: ByteArray
): ContentType? = entries.find {
): MediaType? = entries.find {
it.detect(bytes)
}

Expand All @@ -62,18 +65,18 @@ public enum class ContentType(
}

public fun ByteArray.startsWith(
vararg values: String
): Boolean = values.any {
(size >= it.length)
&& sliceArray(0 ..< it.length)
.contentEquals(it.encodeToByteArray())
}
data: String
): Boolean = (size >= data.length)
&& sliceArray(0 ..< data.length)
.contentEquals(data.encodeToByteArray())

@OptIn(ExperimentalUnsignedTypes::class)
public fun ByteArray.startsWith(
vararg bytes: UByte
): Boolean = size >= bytes.size && sliceArray(0 ..< bytes.size).toUByteArray().contentEquals(bytes)
): Boolean = (size >= bytes.size)
&& sliceArray(0 ..< bytes.size)
.toUByteArray().contentEquals(bytes)

public fun ByteArray.detectContentType(): ContentType? = ContentType.detect(this)
public fun ByteArray.detectMediaType(): MediaType? = MediaType.detect(this)

public fun Path.detectContentType(): ContentType? = toBytes().detectContentType()
public fun Path.detectMediaType(): MediaType? = readBytes().detectMediaType()
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/Paths.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import kotlinx.io.files.SystemFileSystem
import kotlinx.io.readByteArray
import kotlinx.io.readString

public fun Path.toBytes(): ByteArray = SystemFileSystem.source(
public fun Path.readBytes(): ByteArray = SystemFileSystem.source(
this
).buffered().use {
it.readByteArray()
Expand Down
59 changes: 0 additions & 59 deletions src/commonTest/kotlin/ContentTypeTest.kt

This file was deleted.

59 changes: 59 additions & 0 deletions src/commonTest/kotlin/MediaTypeTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2024 Kazimierz Pogoda / Xemantic
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.xemantic.ai.file.magic

import com.xemantic.ai.file.magic.test.MINIMAL_GIF
import com.xemantic.ai.file.magic.test.MINIMAL_JPEG
import com.xemantic.ai.file.magic.test.MINIMAL_PDF
import com.xemantic.ai.file.magic.test.MINIMAL_PNG
import com.xemantic.ai.file.magic.test.MINIMAL_WEBP
import com.xemantic.ai.file.magic.test.isBrowserTest
import com.xemantic.ai.file.magic.test.testDataDir
import com.xemantic.kotlin.test.assert
import kotlinx.io.files.Path
import kotlin.test.Test

class MediaTypeTest {

@Test
fun `Should detect MediaTypes`() {
assert(byteArrayOf().detectMediaType() == null)
assert("foo".encodeToByteArray().detectMediaType() == null)
assert(MINIMAL_PDF.detectMediaType() == MediaType.PDF)
assert(MINIMAL_JPEG.detectMediaType() == MediaType.JPEG)
assert(MINIMAL_PNG.detectMediaType() == MediaType.PNG)
assert(MINIMAL_WEBP.detectMediaType() == MediaType.WEBP)
assert(MINIMAL_GIF.detectMediaType() == MediaType.GIF)
}

@Test
fun `Should detect MediaTypes of Paths`() {
if (isBrowserTest) return // we don't have file access in the browser, but we do have with node.js
assert(Path(testDataDir, "minimal.gif").detectMediaType() == MediaType.GIF)
assert(Path(testDataDir, "minimal.jpeg").detectMediaType() == MediaType.JPEG)
assert(Path(testDataDir, "minimal.pdf").detectMediaType() == MediaType.PDF)
assert(Path(testDataDir, "minimal.png").detectMediaType() == MediaType.PNG)
assert(Path(testDataDir, "minimal.webp").detectMediaType() == MediaType.WEBP)
}

@Test
fun `Should not detect MediaTypes of a Path with empty file`() {
if (isBrowserTest) return // we don't have file access in the browser, but we do have with node.js
assert(Path(testDataDir, "zero.txt").detectMediaType() == null)
}

}

0 comments on commit dd55787

Please sign in to comment.