How to get the target object value from a PropertyDrawer for an array of objects?

I have a serializable class. Something like:

[Serializable]
public class Data
{
    public Category Category;
    public int Size1D;
    public Vector3 Size3D;
}

public enum Category
{
    Cat1=0,
    Cat2=1
}

I want to be able to describe an array of such objects inside a MonoBehaviour via inspector

public class Definition : MonoBehaviour
{
    public Data[] Data;
}

in such a way that for each array element, Size1D and Size3D properties are available for editing based on Category value, i.e. if Category==Cat1 then Size1D is available for editing in the inspector and Size3D is not and vice versa for Category==Cat2.
In order to do this I implemented a PropertyDrawer for Data class:

[CustomPropertyDrawer(typeof(Data))]
public class DataPropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // some GUI stuff here
    }
}

The problem appears when I try to condition the GUI based on Category. In order to do this I need to retrieve the Category value. As I understand the way to do this is by using an expression like this

fieldInfo.GetValue(property.serializedObject.targetObject)

inside OnGUI. I expected it to return the corresponding Data object, but it returns Data, i.e. an array of Data objects that MonoBehaviour property is assigned to. This seems confusing to me since OnGUI renders stuff for each of the Data objects, but the corresponding target value is array and not the corresponding element.

I suspect I could go another way and hide Data inside some other class and write a PropertyDrawer for it instead, but this seems like a much more complex solution. Is there a way to implement a PropertyDrawer for Data class that would have the desired behaviour?

You need to get the enum value of the category and then display depending on it. You need to find the relative property.

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(Data))]
public class DataPropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginProperty(position, label, property);

        var indent = EditorGUI.indentLevel;
        EditorGUI.indentLevel = 0;

        var carRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
        var secondRect = new Rect(position.x, position.y + 20f, position.width, EditorGUIUtility.singleLineHeight);

        var category = property.FindPropertyRelative("Category");

        category.intValue = EditorGUI.Popup(carRect, "Catergory", category.intValue, category.enumNames);

        switch ((Category)category.intValue)
        {
            case Category.Cat1:
                var size1d = property.FindPropertyRelative("Size1D");
                size1d.intValue = EditorGUI.IntField(secondRect, "Size1D", size1d.intValue);
                break;
            case Category.Cat2:
                var size3d = property.FindPropertyRelative("Size3D");
                size3d.vector3Value = EditorGUI.Vector3Field(secondRect, "Size3D", size3d.vector3Value);
                break;
        }

        EditorGUI.indentLevel = indent;

        EditorGUI.EndProperty();
    }

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return (20 - EditorGUIUtility.singleLineHeight) + (EditorGUIUtility.singleLineHeight * 2);
    }
}