Skip to content

Commit 459d80a

Browse files
committed
Refactored property system to align get/notify/dispose with folder watcher and readonly/mutable/modifiable with folder type tree.
Fixes issue with previous setup that required SystemFile and SystemFolder instances to be disposable, rather than the property watcher being disposable. Enables properties to be yielded from IFolder.GetItemsAsync() async enumerable in the future, or to implement IFile for loosely-typed mass property enumeration. See internal notes and public discord discussion 12/30/2025 https://discord.com/channels/372137812037730304/1443993977262178396
1 parent aabc7cc commit 459d80a

File tree

47 files changed

+765
-431
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+765
-431
lines changed

src/IFolderWatcher.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ public interface IFolderWatcher : INotifyCollectionChanged, IDisposable, IAsyncD
1212
/// Gets the folder being watched for changes.
1313
/// </summary>
1414
IMutableFolder Folder { get; }
15-
}
15+
}
Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
1-
using System;
2-
using System.Threading;
3-
using System.Threading.Tasks;
4-
51
namespace OwlCore.Storage;
62

73
/// <summary>
8-
/// Indicates that the storage item supports retrieving the creation timestamp as a <see cref="DateTime"/>.
4+
/// Indicates that the storage item exposes a creation timestamp property.
95
/// </summary>
10-
/// <remarks>
11-
/// <para>
12-
/// <see cref="DateTime"/> is the least common denominator for timestamp properties across storage implementations.
13-
/// The returned value may be timezone-unspecified or implied local time depending on the underlying storage system.
14-
/// When the implementation uses UTC or when only DateTimeOffset is available, it is converted to local time.
15-
/// </para>
16-
/// <para>
17-
/// A <c>null</c> return value indicates the timestamp is unavailable, unset, or could not be retrieved.
18-
/// Sentinel values from underlying storage (e.g., <see cref="DateTime.MinValue"/>, zero) are translated to <c>null</c>.
19-
/// </para>
20-
/// <para>
21-
/// When timezone offset information is required and the implementation can provide it, use <see cref="ICreatedAtOffset"/> instead.
22-
/// </para>
23-
/// </remarks>
246
public interface ICreatedAt
257
{
268
/// <summary>
27-
/// Asynchronously retrieves the creation timestamp of the storage item.
9+
/// Gets the creation timestamp property for this storage item.
2810
/// </summary>
29-
/// <param name="cancellationToken">A token that can be used to cancel the ongoing operation.</param>
30-
/// <returns>A task containing the storage property with the creation timestamp, or <c>null</c> if unavailable or unset.</returns>
31-
Task<IStorageProperty<DateTime?>> GetCreatedAtAsync(CancellationToken cancellationToken);
11+
ICreatedAtProperty CreatedAt { get; }
3212
}
Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
11
using System;
2-
using System.Threading;
3-
using System.Threading.Tasks;
42

53
namespace OwlCore.Storage;
64

75
/// <summary>
8-
/// Indicates that the storage item supports retrieving the creation timestamp as a <see cref="DateTimeOffset"/>.
6+
/// Indicates that the storage item exposes a creation timestamp property with timezone offset information.
97
/// </summary>
108
/// <remarks>
11-
/// <para>
12-
/// Use this interface when the implementation can provide timezone offset information and the consumer needs to preserve the original local time context.
13-
/// <see cref="DateTimeOffset"/> uniquely and unambiguously identifies a single point in time across systems.
14-
/// </para>
15-
/// <para>
16-
/// Not all implementations support offset data—<see cref="DateTime"/> via <see cref="ICreatedAt"/> is the least common denominator.
17-
/// It is easier to discard offset data than to add it when it doesn't exist, so this interface is optional.
18-
/// </para>
19-
/// <para>
20-
/// A <c>null</c> return value indicates the timestamp is unavailable, unset, or could not be retrieved.
21-
/// Sentinel values from underlying storage are translated to <c>null</c>.
22-
/// </para>
9+
/// Extends <see cref="ICreatedAt"/> to also provide <see cref="DateTimeOffset"/>-based access when the
10+
/// underlying implementation can provide timezone offset information.
2311
/// </remarks>
2412
public interface ICreatedAtOffset : ICreatedAt
2513
{
2614
/// <summary>
27-
/// Asynchronously retrieves the creation timestamp of the storage item with timezone offset information.
15+
/// Gets the creation timestamp property with timezone offset information.
2816
/// </summary>
29-
/// <param name="cancellationToken">A token that can be used to cancel the ongoing operation.</param>
30-
/// <returns>A task containing the storage property with the creation timestamp and offset, or <c>null</c> if unavailable or unset.</returns>
31-
Task<IStorageProperty<DateTimeOffset?>> GetCreatedAtOffsetAsync(CancellationToken cancellationToken);
17+
ICreatedAtOffsetProperty CreatedAtOffset { get; }
3218
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
namespace OwlCore.Storage;
4+
5+
/// <summary>
6+
/// A storage property representing the creation timestamp as a <see cref="DateTimeOffset"/>.
7+
/// </summary>
8+
/// <remarks>
9+
/// <para>
10+
/// Use this interface when the implementation can provide timezone offset information and the consumer needs to preserve the original local time context.
11+
/// <see cref="DateTimeOffset"/> uniquely and unambiguously identifies a single point in time across systems.
12+
/// </para>
13+
/// <para>
14+
/// Not all implementations support offset data—<see cref="DateTime"/> via <see cref="ICreatedAtProperty"/> is the least common denominator.
15+
/// It is easier to discard offset data than to add it when it doesn't exist, so this interface is optional.
16+
/// </para>
17+
/// <para>
18+
/// A <c>null</c> return value from <see cref="IStorageProperty{T}.GetValueAsync"/> indicates the timestamp is unavailable, unset, or could not be retrieved.
19+
/// Sentinel values from underlying storage are translated to <c>null</c>.
20+
/// </para>
21+
/// </remarks>
22+
public interface ICreatedAtOffsetProperty : IStorageProperty<DateTimeOffset?>
23+
{
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
namespace OwlCore.Storage;
4+
5+
/// <summary>
6+
/// A storage property representing the creation timestamp as a <see cref="DateTime"/>.
7+
/// </summary>
8+
/// <remarks>
9+
/// <para>
10+
/// <see cref="DateTime"/> is the least common denominator for timestamp properties across storage implementations.
11+
/// The returned value may be timezone-unspecified or implied local time depending on the underlying storage system.
12+
/// When the implementation uses UTC or when only <see cref="DateTimeOffset"/> is available, it is converted to local time.
13+
/// </para>
14+
/// <para>
15+
/// A <c>null</c> return value from <see cref="IStorageProperty{T}.GetValueAsync"/> indicates the timestamp is unavailable, unset, or could not be retrieved.
16+
/// Sentinel values from underlying storage (e.g., <see cref="DateTime.MinValue"/>, zero) are translated to <c>null</c>.
17+
/// </para>
18+
/// <para>
19+
/// When timezone offset information is required and the implementation can provide it, use <see cref="ICreatedAtOffsetProperty"/> instead.
20+
/// </para>
21+
/// </remarks>
22+
public interface ICreatedAtProperty : IStorageProperty<DateTime?>
23+
{
24+
}

src/Properties/CreatedAt/IModifiableCreatedAt.cs

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/Properties/CreatedAt/IModifiableCreatedAtOffset.cs

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
3+
namespace OwlCore.Storage;
4+
5+
/// <summary>
6+
/// Extends <see cref="IMutableCreatedAtOffsetProperty"/> to support updating the creation timestamp with timezone offset.
7+
/// </summary>
8+
/// <remarks>
9+
/// The value passed to <see cref="IModifiableStorageProperty{T}.UpdateValueAsync"/> is non-nullable
10+
/// because most underlying storage systems do not support setting a null or "unset" timestamp value.
11+
/// </remarks>
12+
public interface IModifiableCreatedAtOffsetProperty : IMutableCreatedAtOffsetProperty, IModifiableStorageProperty<DateTimeOffset?>
13+
{
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
3+
namespace OwlCore.Storage;
4+
5+
/// <summary>
6+
/// Extends <see cref="IMutableCreatedAtProperty"/> to support updating the creation timestamp.
7+
/// </summary>
8+
/// <remarks>
9+
/// <para>
10+
/// The value passed to <see cref="IModifiableStorageProperty{T}.UpdateValueAsync"/> is non-nullable
11+
/// because most underlying storage systems do not support setting a null or "unset" timestamp value.
12+
/// </para>
13+
/// <para>
14+
/// Property lifecycle is tied to the property itself; there is no "delete" semantic for individual properties.
15+
/// </para>
16+
/// </remarks>
17+
public interface IModifiableCreatedAtProperty : IMutableCreatedAtProperty, IModifiableStorageProperty<DateTime?>
18+
{
19+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
3+
namespace OwlCore.Storage;
4+
5+
/// <summary>
6+
/// Extends <see cref="ICreatedAtOffsetProperty"/> to support watching for changes to the creation timestamp.
7+
/// </summary>
8+
public interface IMutableCreatedAtOffsetProperty : ICreatedAtOffsetProperty, IMutableStorageProperty<DateTimeOffset?>
9+
{
10+
}

0 commit comments

Comments
 (0)