diff --git a/Project.toml b/Project.toml index 28efdc9..284fbcf 100644 --- a/Project.toml +++ b/Project.toml @@ -8,11 +8,13 @@ RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [weakdeps] +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [extensions] +IntervalSetsPrintfExt = "Printf" IntervalSetsRandomExt = "Random" IntervalSetsRecipesBaseExt = "RecipesBase" IntervalSetsStatisticsExt = "Statistics" @@ -22,6 +24,7 @@ Aqua = "0.8" Dates = "1" OffsetArrays = "1" Plots = "1" +Printf = "1" Random = "1" RecipesBase = "1" Statistics = "1" @@ -34,6 +37,7 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" @@ -41,4 +45,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [targets] -test = ["Aqua", "Dates", "Test", "Plots", "Random", "RecipesBase", "OffsetArrays", "Statistics", "Unitful"] +test = ["Aqua", "Dates", "Test", "Plots", "Printf", "Random", "RecipesBase", "OffsetArrays", "Statistics", "Unitful"] diff --git a/ext/IntervalSetsPrintfExt.jl b/ext/IntervalSetsPrintfExt.jl new file mode 100644 index 0000000..d6f8009 --- /dev/null +++ b/ext/IntervalSetsPrintfExt.jl @@ -0,0 +1,30 @@ +module IntervalSetsPrintfExt + +using Printf +using IntervalSets +using IntervalSets: _show_suffix + +INTERVAL_SEPARATOR = " .. " + +Printf.plength(f::Printf.Spec{<:Printf.Ints}, x::Interval) = + Printf.plength(f, leftendpoint(x)) + Printf.plength(f, rightendpoint(x)) + + ncodeunits(INTERVAL_SEPARATOR) + ncodeunits(_show_suffix(x)) + +# separate methods for disambiguation +Printf.fmt(buf, pos, arg::Interval, spec::Printf.Spec{<:Printf.Floats}) = _fmt(buf, pos, arg, spec) +Printf.fmt(buf, pos, arg::Interval, spec::Printf.Spec{<:Printf.Ints}) = _fmt(buf, pos, arg, spec) + +function _fmt(buf, pos, arg, spec) + pos = Printf.fmt(buf, pos, leftendpoint(arg), spec) + buf[pos:pos+ncodeunits(INTERVAL_SEPARATOR)-1] .= codeunits(INTERVAL_SEPARATOR) + pos += ncodeunits(INTERVAL_SEPARATOR) + pos = Printf.fmt(buf, pos, rightendpoint(arg), spec) + + suf = _show_suffix(arg) + buf[pos:pos+ncodeunits(suf)-1] .= codeunits(suf) + pos += ncodeunits(suf) + + return pos +end + +end \ No newline at end of file diff --git a/src/interval.jl b/src/interval.jl index a35bf39..3cc8fa2 100644 --- a/src/interval.jl +++ b/src/interval.jl @@ -156,10 +156,12 @@ julia> 3 ± 2 ±(x, y) = ClosedInterval(x - y, x + y) ±(x::CartesianIndex, y::CartesianIndex) = ClosedInterval(x-y, x+y) -show(io::IO, I::ClosedInterval) = print(io, leftendpoint(I), " .. ", rightendpoint(I)) -show(io::IO, I::OpenInterval) = print(io, leftendpoint(I), " .. ", rightendpoint(I), " (open)") -show(io::IO, I::Interval{:open,:closed}) = print(io, leftendpoint(I), " .. ", rightendpoint(I), " (open-closed)") -show(io::IO, I::Interval{:closed,:open}) = print(io, leftendpoint(I), " .. ", rightendpoint(I), " (closed-open)") +_show_suffix(::ClosedInterval) = "" +_show_suffix(::OpenInterval) = " (open)" +_show_suffix(::Interval{:open,:closed}) = " (open-closed)" +_show_suffix(::Interval{:closed,:open}) = " (closed-open)" + +show(io::IO, I::Interval) = print(io, leftendpoint(I), " .. ", rightendpoint(I), _show_suffix(I)) # The following are not typestable for mixed endpoint types _left_intersect_type(::Type{Val{:open}}, ::Type{Val{L2}}, a1, a2) where L2 = a1 < a2 ? (a2,L2) : (a1,:open) diff --git a/test/runtests.jl b/test/runtests.jl index d9dc0ea..83e57ca 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,6 +6,7 @@ import Statistics: mean using Random using Unitful using Plots +using Printf import IntervalSets: Domain, endpoints, closedendpoints, TypedEndpointsInterval @@ -443,6 +444,15 @@ struct IncompleteInterval <: AbstractInterval{Int} end @test_throws MethodError 2 in I end + VERSION ≥ v"1.9" && @testset "stringify" begin + @test string(0..1) == "0 .. 1" + @test string(iv"[0,1)") == "0 .. 1 (closed-open)" + @test @sprintf("%d", 0..1) == "0 .. 1" + @test @sprintf("%.2f", 0..1) == "0.00 .. 1.00" + @test @sprintf("%.2f", iv"[0,1)") == "0.00 .. 1.00 (closed-open)" + @test @sprintf("%.2f", 0u"m"..1u"m") == "0.00 m .. 1.00 m" + end + include("base_methods.jl") include("setoperations.jl") include("findall.jl")