Skip to content

Commit

Permalink
Add only as replacement for convert
Browse files Browse the repository at this point in the history
  • Loading branch information
pabloferz committed Jan 17, 2022
1 parent 2fe33fd commit 7e04521
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 26 deletions.
1 change: 1 addition & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ Open
Unbounded
first
last
only
span
isclosed
isopen
Expand Down
6 changes: 6 additions & 0 deletions src/Intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ using Dates: AbstractDateTime, value, coarserperiod

import Base: , , , , union, union!, merge

# Extend `Base.only` when it exists
if VERSION >= v"1.4.0-DEV.142"
import Base: only
end

# Extend `Base.isdisjoint` when it exists
# https://github.com/JuliaLang/julia/pull/34427
if VERSION >= v"1.5.0-DEV.124"
Expand Down Expand Up @@ -54,6 +59,7 @@ export Bound,
HB,
first,
last,
only,
span,
bounds_types,
isclosed,
Expand Down
22 changes: 15 additions & 7 deletions src/anchoredinterval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,23 +176,31 @@ span(interval::AnchoredInterval{P}) where P = abs(P)

##### CONVERSION #####

# Allows an interval to be converted to a scalar when the set contained by the interval only
# contains a single element.
function only(interval::AnchoredInterval{P}) where {P}
if isclosed(interval) && (sign(P) == 0 || first(interval) == last(interval))
return first(interval)
else
throw(DomainError(interval, "The interval is not closed with coinciding endpoints"))
end
end

# Remove in version 2.0.0
function Base.convert(::Type{T}, interval::AnchoredInterval{P,T}) where {P,T}
if isclosed(interval) && (sign(P) == 0 || first(interval) == last(interval))
depwarn(
"`convert(::Type{T}, interval::AnchoredInterval{P,T})` is deprecated, " *
"use `only(interval::AnchoredInterval{P,T})` instead.",
:convert,
)
return first(interval)
else
# Remove deprecation in version 2.0.0
depwarn(
"`convert(T, interval::AnchoredInterval{P,T})` is deprecated for " *
"`convert(::Type{T}, interval::AnchoredInterval{P,T})` is deprecated for " *
"intervals which are not closed with coinciding endpoints. " *
"Use `anchor(interval)` instead.",
:convert,
)
return anchor(interval)

# TODO: For when deprecation is removed
# throw(DomainError(interval, "The interval is not closed with coinciding endpoints"))
end
end

Expand Down
14 changes: 10 additions & 4 deletions src/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -235,18 +235,24 @@ end

##### CONVERSION #####

# Allows an interval to be converted to a scalar when the set contained by the interval only
# contains a single element.
function Base.convert(::Type{T}, interval::Interval{T}) where T
function only(interval::Interval)
if first(interval) == last(interval) && isclosed(interval)
return first(interval)
else
throw(DomainError(interval, "The interval is not closed with coinciding endpoints"))
end
end

##### DISPLAY #####
function Base.convert(::Type{T}, interval::Interval{T}) where {T}
depwarn(
"`convert(::Type{T}, interval::Interval{T})` is deprecated, " *
"use `only(interval)` instead.",
:convert,
)
return only(interval)
end

##### DISPLAY #####

function Base.show(io::IO, interval::Interval{T,L,R}) where {T,L,R}
if get(io, :compact, false)
Expand Down
9 changes: 4 additions & 5 deletions test/anchoredinterval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,16 @@ using Intervals: Bounded, Ending, Beginning, canonicalize, isunbounded

@testset "conversion" begin
interval = AnchoredInterval{Hour(0)}(dt)
@test convert(DateTime, interval) == dt
@test only(interval) == dt

he = HourEnding(dt)
hb = HourBeginning(dt)

# Note: When the deprecation is dropped remove the deprecated tests and uncomment
# the DomainError tests
@test_throws DomainError only(he)
@test_throws DomainError only(hb)

@test (@test_deprecated convert(DateTime, he)) == anchor(he)
@test (@test_deprecated convert(DateTime, hb)) == anchor(hb)
# @test_throws DomainError convert(DateTime, he)
# @test_throws DomainError convert(DateTime, hb)

@test convert(Interval, he) == Interval{Open, Closed}(dt - Hour(1), dt)
@test convert(Interval, hb) == Interval{Closed, Open}(dt, dt + Hour(1))
Expand Down
23 changes: 13 additions & 10 deletions test/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,22 @@
end

@testset "conversion" begin
@test_throws DomainError convert(Int, Interval{Open, Open}(10, 10))
@test_throws DomainError convert(Int, Interval{Open, Closed}(10, 10))
@test_throws DomainError convert(Int, Interval{Closed, Open}(10, 10))
@test convert(Int, Interval{Closed, Closed}(10, 10)) == 10
@test_throws DomainError convert(Int, Interval{Closed, Closed}(10, 11))
@test_throws DomainError only(Interval{Open, Open}(10, 10))
@test_throws DomainError only(Interval{Open, Closed}(10, 10))
@test_throws DomainError only(Interval{Closed, Open}(10, 10))
@test only(Interval{Closed, Closed}(10, 10)) == 10
@test_throws DomainError only(Interval{Closed, Closed}(10, 11))

@test (@test_deprecated convert(Int, Interval{Closed, Closed}(10, 10))) == 10
@test_throws DomainError (@test_deprecated convert(Int, Interval{Closed, Closed}(10, 11)))

for T in (Date, DateTime)
dt = T(2013, 2, 13)
@test_throws DomainError convert(T, Interval{Open, Open}(dt, dt))
@test_throws DomainError convert(T, Interval{Open, Closed}(dt, dt))
@test_throws DomainError convert(T, Interval{Closed, Open}(dt, dt))
@test convert(T, Interval{Closed, Closed}(dt, dt)) == dt
@test_throws DomainError convert(T, Interval{Closed, Closed}(dt, dt + Day(1)))
@test_throws DomainError only(Interval{Open, Open}(dt, dt))
@test_throws DomainError only(Interval{Open, Closed}(dt, dt))
@test_throws DomainError only(Interval{Closed, Open}(dt, dt))
@test only(Interval{Closed, Closed}(dt, dt)) == dt
@test_throws DomainError only(Interval{Closed, Closed}(dt, dt + Day(1)))
end
end

Expand Down

0 comments on commit 7e04521

Please sign in to comment.